(function (root, factory) { //amd if (typeof define === "function" && define.amd) { define(['sprintf-js'], function (sprintf) { return factory(sprintf.vsprintf); }); //commonjs } else if (typeof module === "object" && module.exports) { module.exports = factory(require('sprintf-js').vsprintf); //global } else { root.Translator = factory(window.vsprintf); } var i18n = new Translator(TRANSLATIONS); window['__'] = function (sMsg, sGroupID) { return i18n.p__(sGroupID, sMsg); }; window['__pn'] = function (sMsgID, sGroupID, iValue) { if (iValue === undefined || I18N_FN.isNumber(iValue) === false) { iValue = 0; } return i18n.np__(sGroupID, sMsgID, sMsgID + '.PLURAL', iValue); }; }(this, function (vsprintf) { "use strict"; function Translator (translations) { this.dictionary = {}; this.plurals = {}; this.domain = null; if (translations) { this.loadTranslations(translations); } } Translator.prototype = { loadTranslations: function (translations) { var domain = translations.domain || ''; if (this.domain === null) { this.domain = domain; } if (this.dictionary[domain]) { mergeTranslations(this.dictionary[domain], translations.messages); return this; } if (translations.fn) { this.plurals[domain] = { fn: translations.fn }; } else if (translations['plural-forms']) { var plural = translations['plural-forms'].split(';', 2); this.plurals[domain] = { count: parseInt(plural[0].replace('nplurals=', '')), code: plural[1].replace('plural=', 'return ') + ';' }; } this.dictionary[domain] = translations.messages; return this; }, defaultDomain: function (domain) { this.domain = domain; return this; }, gettext: function (original) { return this.dpgettext(this.domain, null, original); }, ngettext: function (original, plural, value) { return this.dnpgettext(this.domain, null, original, plural, value); }, dngettext: function (domain, original, plural, value) { return this.dnpgettext(domain, null, original, plural, value); }, npgettext: function (context, original, plural, value) { return this.dnpgettext(this.domain, context, original, plural, value); }, pgettext: function (context, original) { return this.dpgettext(this.domain, context, original); }, dgettext: function (domain, original) { return this.dpgettext(domain, null, original); }, dpgettext: function (domain, context, original) { var translation = getTranslation(this.dictionary, domain, context, original); if (translation !== false && translation[0] !== '') { return translation[0]; } return original; }, dnpgettext: function (domain, context, original, plural, value) { var index = getPluralIndex(this.plurals, domain, value); var translation = getTranslation(this.dictionary, domain, context, original); if (translation[index] && translation[index] !== '') { return translation[index]; } return (index === 0) ? original : plural; }, __: function (original) { return format( this.gettext(original), Array.prototype.slice.call(arguments, 1) ); }, n__: function (original, plural, value) { return format( this.ngettext(original, plural, value), Array.prototype.slice.call(arguments, 3) ); }, p__: function (context, original) { return format( this.pgettext(context, original), Array.prototype.slice.call(arguments, 2) ); }, d__: function (domain, original) { return format( this.dgettext(domain, original), Array.prototype.slice.call(arguments, 2) ); }, dp__: function (domain, context, original) { return format( this.dgettext(domain, context, original), Array.prototype.slice.call(arguments, 3) ); }, np__: function (context, original, plural, value) { return format( this.npgettext(context, original, plural, value), Array.prototype.slice.call(arguments, 4) ); }, dnp__: function (domain, context, original, plural, value) { return format( this.dnpgettext(domain, context, original, plural, value), Array.prototype.slice.call(arguments, 5) ); } }; function getTranslation(dictionary, domain, context, original) { context = context || ''; if (!dictionary[domain] || !dictionary[domain][context] || !dictionary[domain][context][original]) { return false; } try { I18N_LOG_COLLECT.set(original, context); }catch (e) {} return dictionary[domain][context][original]; } function getPluralIndex(plurals, domain, value) { if (!plurals[domain]) { return value == 1 ? 0 : 1; } if (!plurals[domain].fn) { plurals[domain].fn = new Function('n', plurals[domain].code); } return plurals[domain].fn.call(this, value) + 0; } function mergeTranslations(translations, newTranslations) { for (var context in newTranslations) { if (!translations[context]) { translations[context] = newTranslations[context]; continue; } for (var original in newTranslations[context]) { translations[context][original] = newTranslations[context][original]; } } } function format (text, args) { if (!args.length) { return text; } if (args[0] instanceof Array) { return vsprintf(text, args[0]); } return vsprintf(text, args); } return Translator; })); /** * i18n 관련 함수 모음 * @type {{ordinalSuffixes: string[], ordinalNumber: I18N_FN.ordinalNumber}} */ var I18N_FN = { ordinalSuffixes: ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'], ordinalNumber: function (iValue) { if (iValue === undefined){ return ''; } var iNum = String(iValue).replace(/,/g, ""); if (this.isNumber(iNum) === false) { return iValue; } if (__('__LANGUAGE.CODE__') !== 'en_US') { return iValue; } iNum = Math.abs(iNum); iNum = parseFloat(iNum); if (((iNum % 100) >= 11 && ((iNum % 100) <= 13)) || iNum % 1 != 0) { return iValue + 'th'; } return iValue + this.ordinalSuffixes[iNum % 10]; }, isNumber: function (v) { return /^[+-]?\d*(\.?\d*)$/.test(v); } } var I18N_LOG_COLLECT = { aTranslationCodes : [], bIsCallApiOnLoaded: false, request_url : window.location.pathname, call : function () { var data = I18N_LOG_COLLECT.aTranslationCodes; if (data.length === 0) { return false; } I18N_LOG_COLLECT.aTranslationCodes = []; $.ajax({ url : '/exec/common/translate/logging', data : {"data": data}, type : 'POST', dataType: 'json', success : function (aData) {} }); }, set : function (sMsg_id, sGroup_id) { if (typeof EC_TRANSLATE_LOG_STATUS == 'undefined' || EC_TRANSLATE_LOG_STATUS !== 'T') { return; } var item = { 'request_url': I18N_LOG_COLLECT.request_url, 'msg_id' : sMsg_id, 'group_id' : sGroup_id }; if (I18N_LOG_COLLECT.bIsCallApiOnLoaded) { I18N_LOG_COLLECT.aTranslationCodes.push(item); I18N_LOG_COLLECT.call(); return true; } I18N_LOG_COLLECT.aTranslationCodes.push(item); }, loadComplete: function () { I18N_LOG_COLLECT.bIsCallApiOnLoaded = true; I18N_LOG_COLLECT.call(); } }; if (typeof EC_TRANSLATE_LOG_STATUS != 'undefined' && EC_TRANSLATE_LOG_STATUS === 'T') { if (document.addEventListener) { document.addEventListener("DOMContentLoaded", function () { I18N_LOG_COLLECT.loadComplete(); }, false); } else if (document.attachEvent) { document.attachEvent("onreadystatechange", function () { if (document.readyState === "complete") { document.detachEvent("onreadystatechange", arguments.callee); I18N_LOG_COLLECT.loadComplete(); } }); } } /*! * jQuery JavaScript Library v1.4.4 * http://jquery.com/ * * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2010, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Thu Nov 11 19:04:53 2010 -0500 */ (function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h= h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;kd)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La, "`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this, e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a, "margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+ a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/, C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j, s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this, j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length}, toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j=== -1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false; if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload", b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&& !F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&& l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H
a";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"), k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false, scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent= false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom= 1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="
";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="
t
";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display= "none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h= c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando); else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one"; if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true}, attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&& b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0}; c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem, arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid= d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+ c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType=== 8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k=== "click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+ d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired= B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type=== "file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]=== 0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}}); (function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3]; break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr, q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h= l;g.sort(w);if(h)for(var i=1;i0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n, m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled=== true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"=== g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return in[3]-0},nth:function(g,i,n){return n[3]- 0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()=== i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]]; if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m, g);else if(typeof g.length==="number")for(var p=g.length;n";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g); n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&& function(){var g=k,i=t.createElement("div");i.innerHTML="

";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F|| p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g= t.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition? function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n0)for(var h=d;h0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h= h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context): c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a, 2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a, b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&& e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/\s]+\/)>/g,P={option:[1, ""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null; else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1>");try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append", prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument|| b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]===""&&!x?r.childNodes:[];for(o=k.length- 1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script")))); d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i, jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true, zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b), h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b); if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f= d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left; e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/)<[^<]*)*<\/script>/gi, ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b=== "object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("
").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&& !this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})}, getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html", script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data|| !T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache= false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset; A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type", b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&& c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d|| c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]= encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess", [b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"), e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}}); if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show", 3),a,b,d);else{d=0;for(var e=this.length;d=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b, d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a* Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)} var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true; this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide|| this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a= c.timers,b=0;b-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a, e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&& c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase(); c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+ b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window); !function() { 'use strict' // Object.create polyfill if (typeof Object.create != 'function') { Object.create = (function() { var temp = function() {}; return function (prototype) { if (arguments.length > 1) { throw Error(); } if (typeof prototype != 'object') { throw TypeError(); } temp.prototype = prototype; var result = new temp(); temp.prototype = null; return result; }; })(); } var re = { not_string: /[^s]/, not_bool: /[^t]/, not_type: /[^T]/, not_primitive: /[^v]/, number: /[diefg]/, numeric_arg: /[bcdiefguxX]/, json: /[j]/, not_json: /[^j]/, text: /^[^\x25]+/, modulo: /^\x25{2}/, placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/, key: /^([a-z_][a-z_\d]*)/i, key_access: /^\.([a-z_][a-z_\d]*)/i, index_access: /^\[(\d+)\]/, sign: /^[\+\-]/ } function sprintf(key) { try { // `arguments` is not an array, but should be fine for this call return sprintf_format(sprintf_parse(key), arguments); } catch (e) { return key; } } function vsprintf(fmt, argv) { return sprintf.apply(null, [fmt].concat(argv || [])) } function sprintf_format(parse_tree, argv) { var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign for (i = 0; i < tree_length; i++) { if (typeof parse_tree[i] === 'string') { output += parse_tree[i] } else if (typeof parse_tree[i] === 'object') { ph = parse_tree[i] // convenience purposes only if (ph.keys) { // keyword argument arg = argv[cursor] for (k = 0; k < ph.keys.length; k++) { if (arg == undefined) { throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1])) } arg = arg[ph.keys[k]] } } else if (ph.param_no) { // positional argument (explicit) arg = argv[ph.param_no] } else { // positional argument (implicit) arg = argv[cursor++] } if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) { arg = arg() } if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) { throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg)) } if (re.number.test(ph.type)) { is_positive = arg >= 0 } switch (ph.type) { case 'b': arg = parseInt(arg, 10).toString(2) break case 'c': arg = String.fromCharCode(parseInt(arg, 10)) break case 'd': case 'i': arg = parseInt(arg, 10) break case 'j': arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0) break case 'e': arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential() break case 'f': arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg) break case 'g': arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg) break case 'o': arg = (parseInt(arg, 10) >>> 0).toString(8) break case 's': arg = String(arg) arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 't': arg = String(!!arg) arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 'T': arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase() arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 'u': arg = parseInt(arg, 10) >>> 0 break case 'v': arg = arg.valueOf() arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 'x': arg = (parseInt(arg, 10) >>> 0).toString(16) break case 'X': arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase() break } if (re.json.test(ph.type)) { output += arg } else { if (re.number.test(ph.type) && (!is_positive || ph.sign)) { sign = is_positive ? '+' : '-' arg = arg.toString().replace(re.sign, '') } else { sign = '' } pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' ' pad_length = ph.width - (sign + arg).length pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : '' output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg) } } } return output } var sprintf_cache = Object.create(null) function sprintf_parse(fmt) { if (sprintf_cache[fmt]) { return sprintf_cache[fmt] } var _fmt = fmt, match, parse_tree = [], arg_names = 0 while (_fmt) { if ((match = re.text.exec(_fmt)) !== null) { parse_tree.push(match[0]) } else if ((match = re.modulo.exec(_fmt)) !== null) { parse_tree.push('%') } else if ((match = re.placeholder.exec(_fmt)) !== null) { if (match[2]) { arg_names |= 1 var field_list = [], replacement_field = match[2], field_match = [] if ((field_match = re.key.exec(replacement_field)) !== null) { field_list.push(field_match[1]) while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { if ((field_match = re.key_access.exec(replacement_field)) !== null) { field_list.push(field_match[1]) } else if ((field_match = re.index_access.exec(replacement_field)) !== null) { field_list.push(field_match[1]) } else { throw new SyntaxError('[sprintf] failed to parse named argument key') } } } else { throw new SyntaxError('[sprintf] failed to parse named argument key') } match[2] = field_list } else { arg_names |= 2 } if (arg_names === 3) { throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported') } parse_tree.push( { placeholder: match[0], param_no: match[1], keys: match[2], sign: match[3], pad_char: match[4], align: match[5], width: match[6], precision: match[7], type: match[8] } ) } else { throw new SyntaxError('[sprintf] unexpected placeholder') } _fmt = _fmt.substring(match[0].length) } return sprintf_cache[fmt] = parse_tree } /** * export to either browser or node.js */ /* eslint-disable quote-props */ if (typeof exports !== 'undefined') { exports['sprintf'] = sprintf exports['vsprintf'] = vsprintf } if (typeof window !== 'undefined') { window['sprintf'] = sprintf window['vsprintf'] = vsprintf if (typeof define === 'function' && define['amd']) { define(function() { return { 'sprintf': sprintf, 'vsprintf': vsprintf } }) } } /* eslint-enable quote-props */ }(); /* * 각개체 별 항목 컨트롤 을 위해서 차후 확장을 고려 하여 별도로 추출 * */ secondZipcodeHidden(); function secondZipcodeHidden () { //Front Page 우편번호 2번째 엘레멘트 리스트 var secondZipcodeElementId = new Array ( "postcode2", "rzipcode2", "ozipcode2", "zip2", "address_zip2" ); for (var i in secondZipcodeElementId) { try { document.getElementById(secondZipcodeElementId[i]).style.display = "none"; } catch (e){ } } // 구디자인 회원 가입수정 zip2 제거 try { document.frm.zip2.style.display = "none"; } catch (e) { } // 구디자인 배송목록 zip2 제거 try { document.addr_set.rcv_zipcode2.style.display = "none"; } catch (e) { } // 구디자인 주문서 작성 zip2 제거 try { document.frm.rzipcode2.style.display = "none"; document.frm.ozipcode2.style.display = "none"; } catch (e) { } // 구디자인 세금계산서 신청약식 zip2 제거 try { document.frm.mall_zipcode2.style.display = "none"; } catch (e) { } } var EC_PlusAppBridge = (function(){ var bUsePlusAppBridge = false; return { /** * 해당 메소드를 사용해야 플러스앱에 데이터 전달 가능 */ setBridgeFunction: function () { bUsePlusAppBridge = true; }, /** * 플러스앱에 여러 데이터 전달 * @param oBridgeData JSON 타입의 데이터 */ sendBridgeData: function (oBridgeData) { if (bUsePlusAppBridge && typeof (UsePlusAppBridge) !== undefined) { var browserInfo = navigator.userAgent; try { if (browserInfo.indexOf("Cafe24Plus") > -1) { var sBridgeData = JSON.stringify(oBridgeData); if (browserInfo.indexOf("android") > -1) { if (window.PlusAppBridge.hasOwnProperty('sendDatasToApp') === true) { window.PlusAppBridge.sendDatasToApp(sBridgeData); } } else if (typeof (webkit.messageHandlers.sendDatasToApp) !== 'undefined') { webkit.messageHandlers.sendDatasToApp.postMessage(sBridgeData); } } } catch (e) {} } }, /** * 상품 번호 반환 * @param sCheckedProduct */ getProductNo: function (sCheckedProduct) { return sCheckedProduct.split(':')[0]; }, /** * serialize 된 Form을 Json Object 포맷으로 변경 * @param sParam */ unserialize: function (sParam) { var objParam, aParam; aParam = sParam.replace(/\?/, "").split("&"); objParam = {}; $.each(aParam, function(iKey, sValue) { var aValue = sValue.split('='); return objParam[aValue[0]] = aValue[1]; }); return objParam; }, /** * 장바구니 등록 이벤트시 데이터 전송 처리 * @param oParam */ addBasket: function (oParam) { var oData = { type: 'basket', raw_data: oParam }; EC_PlusAppBridge.sendBridgeData(oData); }, /** * 위시리스트 등록 이벤트시 데이터 전송 처리 * @param iProductNo */ addWishList: function (iProductNo) { var oData = { type: 'wish', raw_data: { product_no: iProductNo } }; EC_PlusAppBridge.sendBridgeData(oData); }, /** * 시리얼 쿠폰 등록에 성공시 데이터 전송 처리 * @param string sCouponCode 시리얼 쿠폰 코드 */ addSerialCoupon: function (sCouponCode) { var oData = { type: 'coupon', raw_data: { coupon_code: sCouponCode } }; EC_PlusAppBridge.sendBridgeData(oData); }, /** * 주문 완료 후 데이터 전송 처리 * @param object oParam 주문 완료 데이터 */ addOrderResult: function (oParam) { EC_PlusAppBridge.sendBridgeData(oParam); } } })(); var EC_FRONT_XANS_INTERPRETER = (function() { // 변수 정규표현식 var XANS_VAR_FULL_NAME_REGEXP = '\\{\\$([a-z0-9_\\.]+)(?:[\\s]*[\\|][\\s]*([a-z0-9]+)[\\s]*[:]?((?:[^\\{\\}]+)*))?\\}'; // 템플릿에서 모든 변수를 찾기 위한 정규식 var regexpFindSDEVarFullName = new RegExp(XANS_VAR_FULL_NAME_REGEXP, 'ig'); // '{$var_name|display}'과 같은 문자열에서 변수명과 모디파이어를 분리하기 위한 정규식 var regexpSDEVarFullname = new RegExp('^' + XANS_VAR_FULL_NAME_REGEXP + '$', 'i'); // 모디파이어 var aSDEModifier = { display: function(sVar) { if (sVar) { return ''; } else{ return 'displaynone'; } }, numberformat: function(sVar) { if (isFinite(sVar)) { return number_format(sVar); } else { return ''; } } }; /** * 숫자를 3자리씩 콤마(,)로 끊어서 문자열로 변환하여 리턴합니다. * @param string sNumber 숫자 * @returns {string} 콤마 반영된 문자열 */ function number_format(sNumber) { // 3자리씩 ,로 끊어서 리턴 var sNumber = String(parseInt(sNumber)); var regexp = /^(-?[0-9]+)([0-9]{3})($|\.|,)/; while (regexp.test(sNumber)) { sNumber = sNumber.replace(regexp, "$1,$2$3"); } return sNumber; } /** * 전체 변수명에서 실제 변수명과 모디파이어 등을 분리하여 리턴합니다. * @param string sVarFullName '{$var_name|display}' 형태의 전체 변수명 * @returns {{var_name: *, modifire: *}} */ function parseVariableInfo(sVarFullName) { var aMatches = sVarFullName.match(regexpSDEVarFullname); return { var_name: aMatches[1], modifire: aMatches[2] }; } /** * XANS 템플릿에서 변수를 반영하여 리턴합니다. * @param string sTemplate 템플릿 (HTML) * @param array aVars 변수 리스트 * @return string 완성된 HTML */ function fetch(sTemplate, aVars) { var aHtml = sTemplate.split(''); var sHtml = ''; $(aHtml).each(function(iIndex, sModuleHtml) { if (iIndex < 1 || (iIndex % 2) !== 1) { sHtml += convertHtmlVars(sModuleHtml, aVars); } else { var oObj = $(sModuleHtml); var sChildNode = $('
').append(oObj.children().first().clone()).html(); if (/([\s\S]+)/gm.test(sModuleHtml) === true) { sChildNode = /([\s\S]+)/gm.exec(sModuleHtml)[1].split('')[0]; } var sModuleClass = $(oObj).attr('class'); var sModuleName = ucfirst(sModuleClass.match(/xans-product-([^- ]+)/)[1]); if (typeof(aVars['@' + sModuleName]) === 'object') { var s = ''; $(aVars['@' + sModuleName]).each(function(i, aData) { s += convertHtmlVars(sChildNode, aData); }); if (s !== '') { sHtml += $('
').append(oObj.html(s).clone()).html(); } } } }); return sHtml; } function ucfirst(sString) { if (typeof(sString) !== 'string') { return ''; } return sString.substring(0, 1).toUpperCase() + sString.substring(1).toLowerCase(); } function convertHtmlVars(sTemplate, aVars) { return sTemplate.replace(regexpFindSDEVarFullName, function(sVarFullName) { var aVarInfo = parseVariableInfo(sVarFullName); var sValue = ''; if (aVars[aVarInfo.var_name] || aVars[aVarInfo.var_name] === 0) { sValue = aVars[aVarInfo.var_name]; } if (aVarInfo.modifire !== undefined && aSDEModifier.hasOwnProperty(aVarInfo.modifire) === true) { return aSDEModifier[aVarInfo.modifire](sValue); } else { return sValue; } }); } /** * XANS 템플릿에서 변수 리스트를 얻어서 리턴합니다. * @param string sTemplate 템플릿 (HTML) * @return array 변수 리스트 (ex: ['{$var_name}', '{$var_name|display}']) */ function getVariables(sTemplate) { return sTemplate.match(regexpFindSDEVarFullName); } return { getVariables: getVariables, parseVariableInfo: parseVariableInfo, fetch: fetch }; })(); var EC_FRONT_XANS_TEMPLATE = (function() { // 모듈별 템플릿 var aModuleTemplates = {}; /** * 모듈별 템플릿을 셋팅합니다. * @param string sModuleName 모듈명 (xans-product-listmain-1) * @param string sModuleTemplate 모듈 템플릿 */ function setTemplate(sModuleName, sModuleTemplate) { aModuleTemplates[sModuleName] = sModuleTemplate; if (/^xans-product-list|^xans-product-hashtaglist/.test(sModuleName) === true) { var sTemplateForVDOM = getTemplateForVDOM(sModuleName); var $li = $(sTemplateForVDOM).find('li:first'); var sLiHTMLForVDOM = $('
    ').append($li).html(); // 해시태그 모듈에 대한 별도 캐싱 처리 if (/^xans-product-hashtaglist/.test(sModuleName) === true) { aModuleTemplates[sModuleName] = convertVDomHtmlToHTML(sLiHTMLForVDOM); } else { // oMobileDomData를 여전히 사용중인 사용자js와의 호환성을 위한 예외처리 - ECHOSTING-142586 window.oMobileDomData = { dom: convertVDomHtmlToHTML(sLiHTMLForVDOM), data: EC_FRONT_XANS_INTERPRETER.getVariables(sLiHTMLForVDOM) }; } } } /** * 모듈별 템플릿을 가져옵니다. * @param string sModuleName 모듈명 * @return string 모듈별 템플릿 */ function getTemplate(sModuleName) { if (aModuleTemplates.hasOwnProperty(sModuleName)) { return aModuleTemplates[sModuleName]; } else { return undefined; } } /** * Virtual DOM 에서 사용할 모듈별 템플릿을 가져옵니다. * @param string sModuleName 모듈명 * @return string 모듈별 템플릿 */ function getTemplateForVDOM(sModuleName) { var sTemplate = getTemplate(sModuleName) || ''; // src 속성에 대해 "//:0" 처리해줍니다. var sTemplateForVDOM = sTemplate.replace(/(\s+src\s*=\s*["'])/g, '$1//:0#xansjs'); return sTemplateForVDOM; } /** * "Virtual DOM"용 HTML을 일반 HTML로 변환하여 리턴합니다. * @param string sTemplateForVDOM "Virtual DOM"용 사용한 템플릿 HTML * @return string 일반 HTML */ function convertVDomHtmlToHTML(sTemplateForVDOM) { // src 속성에서 "//:0#xansjs"를 삭제합니다. var sTemplate = sTemplateForVDOM.replace(/(\s+src\s*=\s*["'])\/\/:0#xansjs/g, '$1'); return sTemplate; } return { setTemplate: setTemplate, getTemplate: getTemplate, getTemplateForVDOM: getTemplateForVDOM, convertVDomHtmlToHTML: convertVDomHtmlToHTML }; })(); /** * 모바일 전용 Util * @package app/Mobile * @subpackage Front/Disp/Product * @version 1.0 */ var EC_MOBILE_UTIL = { /* * get li */ convertNode : function(node) { return EC_FRONT_XANS_INTERPRETER.fetch(oMobileDomData.dom, node); }, /* * set default img */ setDefaultImage : function(string, orgStr, repStr) { $(".thumbnail img,img.ThumbImage,img.BigImage").each(function($i,$item){ var $img = new Image(); $img.onerror = function () { $item.src="//img.echosting.cafe24.com/thumb/img_product_big.gif"; } $img.src = this.src; }); }, /* * get ajax url */ getAjaxUrl : function(sModule) { var aAjax = []; aAjax['xans-product-listnormal'] = '/exec/front/Product/ApiProductNormal'; aAjax['xans-product-listmain'] = '/exec/front/Product/ApiProductMain'; return aAjax[sModule]; }, /* * set param */ setAjaxParam : function(aData, sModule) { var aParam = []; if (typeof(aData['cate_no']) === 'number' && aData['cate_no'] > 0) { aParam.push('cate_no=' + aData['cate_no']); } if (typeof(aData['display_group']) === 'number' && aData['display_group'] > 0) { aParam.push('display_group=' + aData['display_group']); } if (typeof(aData['sort_method']) === 'number' && aData['sort_method'] > 0) { aParam.push('sort_method=' + aData['sort_method']); } if (typeof(aData['supplier_code']) === 'string' && aData['supplier_code'] !== '') { aParam.push('supplier_code=' + aData['supplier_code']); } if (typeof(aData['ec_soldout_display']) === 'string' && aData['ec_soldout_display'] !== '') { aParam.push('ec_soldout_display=' + aData['ec_soldout_display']); } aParam.push('page=' + aData['page']); aParam.push('bInitMore=' + aData['bInitMore']); aParam.push('count=' + aData['count']); return this.getAjaxUrl(sModule) + '?' + aParam.join('&'); } }; /* * Swipe 1.0 * * Brad Birdsall, Prime * Copyright 2011, Licensed GPL & MIT * */ ;window.SwipeClient = function(element, options) { // return immediately if element doesn't exist if (! element) { return null; } var _this = this; // retreive options this.options = options || {}; this.index = this.options.startSlide || 0; this.speed = this.options.speed || 300; this.callback = this.options.callback || function() {}; this.delay = this.options.auto || 0; this.postback = this.options.postback || true; // 캐싱 사용유무 (기본값으로 이미 넘어오지만 그래도 no로 한번 더 저장) this.cache = this.options.cache || 'no'; // 현재 슬라이드 개별 모듈의 순서(인덱스)를 저장하기 위해 저장 (상품번호, 카테코리 번호 등으로 조합된 상품별 유니크 값) this.storageId = this.options.elementId || ''; // reference dom elements this.container = element; this.element = this.container.getElementsByTagName('ul')[0]; // the slide pane // static css this.container.style.overflow = 'hidden'; this.element.style.listStyle = 'none'; this.element.style.margin = 0; // trigger slider initialization this.setup(); // begin auto slideshow this.begin(); // add event listeners if (this.element.addEventListener) { this.element.addEventListener('touchstart', this, false); this.element.addEventListener('touchmove', this, false); this.element.addEventListener('touchend', this, false); this.element.addEventListener('touchcancel', this, false); this.element.addEventListener('webkitTransitionEnd', this, false); this.element.addEventListener('msTransitionEnd', this, false); this.element.addEventListener('oTransitionEnd', this, false); this.element.addEventListener('transitionend', this, false); window.addEventListener('resize', this, false); } }; SwipeClient.prototype = { setup: function() { // get and measure amt of slides this.slides = this.element.children; this.length = this.slides.length; // return immediately if their are less than two slides if (this.length < 2) { return null; } // determine width of each slide this.width = Math.ceil(('getBoundingClientRect' in this.container) ? this.container.getBoundingClientRect().width : this.container.offsetWidth); // Fix width for Android WebView (i.e. PhoneGap) if (this.width === 0 && typeof window.getComputedStyle === 'function') { this.width = window.getComputedStyle(this.container, null).width.replace('px',''); } // return immediately if measurement fails if (! this.width) { return null; } // hide slider element but keep positioning during setup var origVisibility = this.container.style.visibility; this.container.style.visibility = 'hidden'; // dynamic css this.element.style.width = Math.ceil(this.slides.length * this.width) + 'px'; var index = this.slides.length; while (index--) { var el = this.slides[index]; el.style.width = this.width + 'px'; el.style.display = 'table-cell'; el.style.verticalAlign = 'top'; } // set start position and force translate to remove initial flickering // 캐싱 사용중일 경우에만 처리 if (this.cache === 'yes') { // 저장된 세선 스토리지 읽어와 처리 // 각 스와이프의 개별 모듈에 해당되는 세션 스토리지 값 // NaN 보다는 parseInt(null)로 명확하게 구분 var iStorageIndexData = parseInt(null); // 상품 상세페이지에서 생성된 세션 스토리지 키 var sStorageDetailName = 'sStorageDetail'; // 상품 상세페이지에서 생성된 세션 스토리지 값 (Unix Timestamp) // NaN 보다는 parseInt(null)로 명확하게 구분 var iStorageDetailData = parseInt(null); // 현재 시간 Unix Timstamp var iNowTime = Math.floor(new Date().getTime() / 1000); // 세션 스토리지 유지 시간 var iSessionTime = 60 * 5; // 값 할당 (int) try { iStorageIndexData = parseInt(sessionStorage.getItem(this.storageId)); iStorageDetailData = parseInt(sessionStorage.getItem(sStorageDetailName)); } catch (e) { } // 저장된 값(추가 이미지)이 삭제된 경우 빈 페이지로 스와이프 되므로, 저장된 인덱스에 해당되는 이미지가 없는 경우는 세션 스토리지 삭제 if (typeof($S.aButton[iStorageIndexData]) === 'undefined') { // 할당된 값 초기화 iStorageIndexData = parseInt(null); // 실제 세션 스토리지에서도 삭제 try { sessionStorage.removeItem(this.storageId); } catch (e) { } } // 값이 있다면 moveTab을 해야 Circle(페이징 원)까지 변경됨 // 상세페이지에서 생성된 세션 스토리지가 특정 시간이 경과하지 않은 경우에만 처리 // 만약 모듈에서 상품번호 등의 정보(this.storageId)를 가져오지 못한 경우에는 처리하지 않음 if (this.storageId !== '' && isNaN(iStorageIndexData) === false && isNaN(iStorageDetailData) === false && iStorageDetailData + iSessionTime >= iNowTime) { // 실제 이동 처리 this.moveTab(iStorageIndexData, 0); } else { this.slide(this.index, 0); } } else { this.slide(this.index, 0); } this.container.style.visibility = origVisibility; }, slide: function(index, duration) { // if useing ajax load try { if (oMobileSliderData.sPictorialLoad === true) { if ($S.iAjax === index + 1 && $S.bAjax === true) { $S.callAjax(); } } } catch (e) {} var style = this.element.style; // fallback to default speed if (duration == undefined) { duration = this.speed; } // set duration speed (0 represents 1-to-1 scrolling) style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = duration + 'ms'; // translate to given index position style.MozTransform = style.webkitTransform = 'translate3d(' + -(index * this.width) + 'px, 0, 0)'; style.msTransform = style.OTransform = 'translateX(' + -(index * this.width) + 'px)'; // set new index to allow for expression arguments this.index = index; // 현재 모듈의 인덱스를 세선 스토리지에 저장 // 캐시 사용중이며 인덱스가 있으면서 저장할 스토리지 ID 값이 있는 경우에만 처리 if (this.cache === 'yes' && isNaN(this.index) === false && this.storageId !== '') { try { sessionStorage.setItem(this.storageId, this.index); } catch (e) { } } }, getPos: function() { // return current index position return this.index; }, prev: function(delay, postback) { // cancel next scheduled automatic transition, if any this.delay = delay || 0; this.postback = (postback == undefined) ? true : postback; clearTimeout(this.interval); if (this.index) { this.slide(this.index - 1, this.speed); } else { if (this.postback !== false) { this.slide(this.length - 1, this.speed); //if first slide return to end } } }, next: function(delay, postback) { // cancel next scheduled automatic transition, if any this.delay = delay || 0; this.postback = (postback == undefined) ? true : postback; clearTimeout(this.interval); if (this.index < this.length - 1) { this.slide(this.index + 1, this.speed); } else { if (this.postback !== false) { this.slide(0, this.speed); //if last slide return to start } } }, moveTab: function(iPage, delay, oTarget) { // control current tab action // 모바일 상품상세에서 slide영역을 다시 원복함 this.index = iPage; this.delay = delay || 0; clearTimeout(this.interval); this.slide(this.index, this.speed); if (typeof(EC_SHOP_FRONT_NEW_OPTION_EXTRA_IMAGE) !== 'undefined') { EC_SHOP_FRONT_NEW_OPTION_EXTRA_IMAGE.setSwipeImage('', true, iPage, oTarget); } }, begin: function() { var _this = this; this.interval = (this.delay) ? setTimeout(function() { _this.next(_this.delay); }, this.delay) : 0; }, stop: function() { this.delay = 0; clearTimeout(this.interval); }, resume: function() { this.delay = this.options.auto || 0; this.begin(); }, setLength: function(expand) { this.length = expand; }, handleEvent: function(e) { switch (e.type) { case 'touchstart': this.onTouchStart(e); break; case 'touchmove': this.onTouchMove(e); break; case 'touchcancel': case 'touchend': this.onTouchEnd(e); break; case 'webkitTransitionEnd': case 'msTransitionEnd': case 'oTransitionEnd': case 'transitionend': this.transitionEnd(e); break; case 'resize': this.setup(); break; } }, transitionEnd: function(e) { if (this.delay) { this.begin(); } this.callback(e, this.index, this.slides[this.index], this); }, onTouchStart: function(e) { this.start = { // get touch coordinates for delta calculations in onTouchMove pageX: e.touches[0].pageX, pageY: e.touches[0].pageY, // set initial timestamp of touch sequence time: Number(new Date()) }; // used for testing first onTouchMove event this.isScrolling = undefined; // reset deltaX this.deltaX = 0; // set transition time to 0 for 1-to-1 touch movement this.element.style.MozTransitionDuration = this.element.style.webkitTransitionDuration = 0; e.stopPropagation(); }, onTouchMove: function(e) { // ensure swiping with one touch and not pinching if (e.touches.length > 1 || e.scale && e.scale !== 1) { return; } this.deltaX = e.touches[0].pageX - this.start.pageX; // determine if scrolling test has run - one time test if (typeof this.isScrolling == 'undefined') { this.isScrolling = !! (this.isScrolling || Math.abs(this.deltaX) < Math.abs(e.touches[0].pageY - this.start.pageY)); } // if user is not trying to scroll vertically if (! this.isScrolling) { // prevent native scrolling e.preventDefault(); // cancel slideshow clearTimeout(this.interval); // increase resistance if first or last slide this.deltaX = this.deltaX / ((! this.index && this.deltaX > 0 // if first slide and sliding left || this.index == this.length - 1 // or if last slide and sliding right && this.deltaX < 0 // and if sliding at all ) ? (Math.abs(this.deltaX) / this.width + 1) // determine resistance level : 1); // no resistance if false // translate immediately 1-to-1 this.element.style.MozTransform = this.element.style.webkitTransform = 'translate3d(' + (this.deltaX - this.index * this.width) + 'px,0,0)'; e.stopPropagation(); } }, onTouchEnd: function(e) { // determine if slide attempt triggers next/prev slide var isValidSlide = Number(new Date()) - this.start.time < 250 // if slide duration is less than 250ms && Math.abs(this.deltaX) > 20 // and if slide amt is greater than 20px || Math.abs(this.deltaX) > this.width/2, // or if slide amt is greater than half the width // determine if slide attempt is past start and end isPastBounds = ! this.index && this.deltaX > 0 // if first slide and slide amt is greater than 0 || this.index == this.length - 1 && this.deltaX < 0; // or if last slide and slide amt is less than 0 // if not scrolling vertically if (! this.isScrolling) { // call slide function with slide end value based on isValidSlide and isPastBounds tests this.slide(this.index + (isValidSlide && ! isPastBounds ? (this.deltaX < 0 ? 1 : -1) : 0 ), this.speed); } e.stopPropagation(); } }; /** * 모바일 상품 더보기 모듈 * @package app/Mobile * @subpackage Front/Disp/Product * @version 2.2 * * * version 2.2 변경사항 * 1. cache = yes 설정으로 더보기 리스트 유지 * 2. 사용자 html 수정 유무에 상관없이 리스팅 * 3. api에 $review_cnt 추가 */ var $M = { /* * current module name */ sModule : 'xans-product-listnormal', /* * current module name */ sMore : 'xans-product-listmore', /* * 더보기 버튼에 대한 중복 실행을 막기 위한 flag */ bLoading : false, /* * 모듈별로 object 값 */ oModuleLoading : {}, /* * init */ init : function() { if (this.sModule == 'xans-product-listnormal') { // 일반상품에 대해 더보기 기능 적용시 페이징 모듈 자동 삭제 $('.xans-product-normalpaging').remove(); } }, /* * show more * @param int iActive 모듈 key * @param int iDisplayGroup 추천/신상품 분류 * @param int iCategoryNo 카테고리 번호 * @param int iCount 주석변수 상품 수 * @param int iSortMethod 정렬방법 * @param string sSupplierCode 공급사코드 * @param bool bInitMore 더보기 기능 초기화 여부 * @param string 품절상품 표시 여부 */ displayMore : function(iActive, iDisplayGroup, iCategoryNo, iCount, iSortMethod, bCache, sSupplierCode, bInitMore, sSoldoutDisplay) { if (this.oModuleLoading[iDisplayGroup] === true) { // 로딩 중에는 실행 안함 return; } var EC_MORE = (function() { var sTargetModuleName, sLiTemplate, sFirstLiTemplate, $moreButton, $currentPageText, sCurrentPageCookieName, iRequestPageNum; /** * 추가될 상품 정보가 append될 모듈명 * @returns {string} */ function getTargetModuleName() { if (iActive > 0) { return $M.sModule + '-' + iActive; } else { return $M.sModule; } } /** * LI 템플릿을 리턴합니다. * @returns {string} */ function getLiTemplate(sPos) { var sModuleHtmlForVDOM = EC_FRONT_XANS_TEMPLATE.getTemplateForVDOM(sTargetModuleName); var $li = $(sModuleHtmlForVDOM).find('ul:first > li:'+sPos); var sLiHtmlForVDOM = $('
      ').append($li).html(); return EC_FRONT_XANS_TEMPLATE.convertVDomHtmlToHTML(sLiHtmlForVDOM); } /** * "더보기" 버튼 모듈 * @returns {jQuery} */ function getMoreButtonElement() { if (iActive > 0) { return $('.' + $M.sMore + '-' + iActive); } else { return $('.' + $M.sMore); } } /** * "현재페이지 표시" 영역 * @returns {jQuery} */ function getCurrentPageTextElement() { if (iDisplayGroup > 1) { return $('#more_current_page_' + iDisplayGroup); } else { return $('#more_current_page'); } } /** * "캐쉬된 현재페이지" 쿠키명 * @returns {string} */ function getCachedCurrentPageCookieName() { var aCookieName = ['mobile_more_current_page']; if (iCategoryNo > 0) { aCookieName.push(iCategoryNo); } if (iDisplayGroup > 1) { aCookieName.push(iDisplayGroup); } return aCookieName.join('_'); } /** * 요청할 페이지 번호를 구하여 리턴합니다. * @return int * "더보기 유지 기능 사용" + "더보기 초기화"인 경우 현재 쿠키에 저장된 페이지 번호 * 그 외에는 다음에 가져올 페이지 번호 */ function getRequestPageNum() { if (bCache === true && bInitMore === true) { // "더보기 유지 기능 사용" + "더보기 초기화"인 경우 var sCookieCurrentPage = $.cookie(sCurrentPageCookieName); if (sCookieCurrentPage) { return parseInt(sCookieCurrentPage, 10); } else { return 1; } } else { // 그 외 var iCurrentPage = $moreButton.data('current_page'); if (iCurrentPage === undefined) { iCurrentPage = 1; } return iCurrentPage + 1; } } /** * 다음 페이지 상품 정보를 가져올 수 있는 ajax URL을 리턴합니다. * @returns string */ function getAjaxUrl() { var aParam = { cate_no : iCategoryNo, display_group : iDisplayGroup, supplier_code : sSupplierCode, sort_method : iSortMethod, page : iRequestPageNum, count : iCount, bInitMore : (bInitMore === true) ? 'T' : 'F', ec_soldout_display : sSoldoutDisplay }; return EC_MOBILE_UTIL.setAjaxParam(aParam, $M.sModule); } /** * 다음 페이지 상품 정보를 UL Element에 추가해줍니다. * @param array aData 상품 정보 */ function appendMoreData(aData) { var aHtml = []; var sTemplate = sLiTemplate; $(aData).each(function(iIndex, aVar) { if (iIndex === 0) { sTemplate = sFirstLiTemplate; } else { sTemplate = sLiTemplate; } aHtml.push(EC_FRONT_XANS_INTERPRETER.fetch(sTemplate, aVar)); }); var sHtml = aHtml.join(''); $('.' + sTargetModuleName).each(function() { $(this).find('ul:first').append(sHtml); }); $currentPageText.text(iRequestPageNum); $moreButton.data('current_page', iRequestPageNum); // 캐시 기능 사용이면 쿠키에 현재 페이지 저장 if (bCache === true) { $.cookie(sCurrentPageCookieName, iRequestPageNum, { expires: 1 }); } } /** * '더보기' 버튼을 숨김 처리합니다. */ function hideMoreButton() { $moreButton.remove(); } /** * Ajax 요청 여부를 리턴합니다. * @return bool true이면 ajax 요청, false이면 ajax 요청 안함 */ function isCallAjax() { if (bInitMore === true && iRequestPageNum <= 1) { // 더보기 유지 기능 동작이고 iRequestPageNum 값이 1이하이면 요청 안함 return false; } return true; } function setMoreAction(data) { if (data.rtn_data.end === true) { EC_MORE.hideMoreButton(); } if (data.is_new_product === true) { EC_SHOP_FRONT_REVIEW_TALK_REVIEW_COUNT.setReviewTalkCnt(); } } sTargetModuleName = getTargetModuleName(); sFirstLiTemplate = getLiTemplate('first'); sLiTemplate = getLiTemplate('last'); $moreButton = getMoreButtonElement(); $currentPageText = getCurrentPageTextElement(); sCurrentPageCookieName = getCachedCurrentPageCookieName(); iRequestPageNum = getRequestPageNum(); return { isCallAjax: isCallAjax, getAjaxUrl: getAjaxUrl, appendMoreData: appendMoreData, hideMoreButton: hideMoreButton, setMoreAction: setMoreAction }; })(); // ajax if (EC_MORE.isCallAjax() === true) { var aParamData = {}; if ($('#ec-product-searchdata-form').length > 0 ) { $('#ec-product-searchdata-catenum').val(iCategoryNo); EC_FRONT_PRODUCT_SEARCH_DATA.setSearchPriceData(); $('#ec-product-searchdata-form .ec-product-searchdata-form:checked').each(function(idx) { var sValues = decodeURIComponent($(this).val()); if ($(this).val() !== sValues ) { $(this).val(encodeURIComponent(sValues)); } else { $(this).val(encodeURIComponent($(this).val())); } }); $('#ec-product-searchdata-form .ec-product-searchdata-form.ec_search_selected').each(function() { if ($(this).attr('type') !== 'checkbox') { $('').attr({type: 'hidden',name: 'search_form[option_data][]',value: encodeURIComponent($(this).attr('sValue'))}).appendTo('#ec-product-searchdata-form'); } }); aParamData = $('#ec-product-searchdata-form').serialize(); } var iGetCategory = iCategoryNo; var iGetDisplay = iDisplayGroup; if (iGetCategory === 0) { iGetCategory = 1; } if (iGetDisplay === 0) { iGetDisplay = 1; } // 저장된 세선 스토리지 읽어와 처리 // 각 더보기의 개별 모듈에 해당되는 세션 스토리지 키 var sStorageListName = 'sStorageList_' + iGetCategory + '_' + iGetDisplay; // 각 더보기의 개별 모듈에 해당되는 세션 스토리지 값 var sStorageListData = null; // 상품 상세페이지에서 생성된 세션 스토리지 키 var sStorageDetailName = 'sStorageDetail'; // 상품 상세페이지에서 생성된 세션 스토리지 값 (Unix Timestamp) var sStorageDetailData = null; // 현재 시간 Unix Timstamp var iNowTime = Math.floor(new Date().getTime() / 1000); // 세션 스토리지 유지 시간 var iSessionTime = 60 * 5; try { sStorageListData = sessionStorage.getItem(sStorageListName); sStorageDetailData = sessionStorage.getItem(sStorageDetailName); } catch (e) { } // 상세페이지에서 생성된 세션 스토리지가 특정 시간이 경과하지 않은 경우에만 캐싱 데이터 사용 if (sStorageDetailData !== null && parseInt(sStorageDetailData) + iSessionTime >= iNowTime) { if (bInitMore === true && sStorageListData !== null) { var oReturnData = JSON.parse(sStorageListData); EC_MORE.appendMoreData(oReturnData.rtn_data.data); EC_MORE.setMoreAction(oReturnData); return; } } $.ajax({ type: 'get', url: EC_MORE.getAjaxUrl(), data: aParamData, dataType: 'json', success: function(data) { if (data.rtn_code === '1000') { EC_MORE.appendMoreData(data.rtn_data.data); EC_MORE.setMoreAction(data); // 초기 구동이 아니면서 세션 스토리지에 데이터가 있는 경우에는 append if (bInitMore === false && sStorageListData !== null) { data.rtn_data.data = JSON.parse(sStorageListData).rtn_data.data.concat(data.rtn_data.data); } // 최종 생성된 데이터 세션 스토리지에 저장 try { sessionStorage.setItem(sStorageListName, JSON.stringify(data)); } catch (e) { } } else { alert('상품을 추가로 더 불러오는 과정에 문제가 발생했습니다. 지속적으로 발생할 경우 운영자에게 문의하세요.'); EC_MORE.hideMoreButton(); return false; } }, error: function (xhr, status, error) { return false; }, beforeSend: function () { $M.oModuleLoading[iDisplayGroup] = true; }, complete: function () { $M.oModuleLoading[iDisplayGroup] = false; } }); } } , setDisplayPageMore : function(iActive, iDisplayGroup, iCategoryNo, iCount, iSortMethod, bCache, sSupplierCode, bInitMore, sSoldoutDisplay) { this.displayMore(iActive, iDisplayGroup, iCategoryNo, iCount, iSortMethod, bCache, sSupplierCode, true, sSoldoutDisplay); } }; /** * 모바일 상품 스와이프 모듈 * @package app/Shop * @subpackage Front/Disp/Product * @since 2014. 2. 12. * @update 2014. 5. 29. * @version 2.2 * * 2.2 개선사항 * 1. 데이터 ajax 로딩 추가 * 2. multi, single 형태 추가 */ var $S = { /* * current module name */ sModule : 'xans-product-listmain', /* * swipe action name */ sModuleSwipe : '', /* * mode */ sMode : 'multi', /* * slider */ bSlider : false, /* * swipeable */ sSwipeable : 'yes', /* * sParam */ sParam : '', /* * grid */ sGrid : 'grid3', /* * grid array */ aGrid : {'grid2':2, 'grid3':3, 'grid4':4, 'grid5':5}, /* * start slide */ iStart : 0, /* * page */ iPage : 1, /* * page block */ iPageBlock : 3, /* * line */ iLine : 1, /* * limit circle */ iLimit : 9, /* * active div */ iActive : 0, /* * save li element */ aElement : [], /* * save circle element */ aButton : [], /* * product class */ $product : null, /* * product ul */ $productModule : null, /* * product list li */ $productList : null, /* * ajax loading */ bAjax : true, /* * generate dom */ bGenerate : false, /* * ajax count */ iAjax : 0, /* * auto slide interval */ iAutoSlideInterval : 0, /* * paging ui */ sPagingType : 'circle', iProductTotal : 0, /* * cache 사용여부 */ sCache : 'no', /* * init */ init : function() { // set param this.setParam(); // set obejct this.setObject(); // set block this.setBlock(); // validate if (this.validate() === false) return; // generate this.generate(); // load swipe this.load(); }, /* * set param */ setParam : function() { try { this.sModuleSwipe = this.sModule.replace(/-/g, "_"); this.iAjax = oMobileSliderData.iSliderLimit; } catch (e) { } }, /* * set block */ setBlock : function() { // set block num this.iPageBlock = (this.sMode == 'multi') ? this.iLine * this.aGrid[this.sGrid] : 1; }, /* * set obejct */ setObject : function() { try { // current module class this.sActiveProduct = this.iActive > 0 ? this.sModule + '-'+this.iActive : this.sModule; // div this.$product = $('.' + this.sActiveProduct); // div > ul this.$productModule = this.$product.find('ul:first'); this.$productModule.css('webkit-backface-visibility', 'hidden'); // div > ul > li > ul > li this.$productList = this.$productModule.find('>li'); } catch (e) { } }, /* * validate */ validate : function() { // not use swipe if (this.sSwipeable != 'yes') return false; // empty ul if (this.$productModule.size() < 1) return false; // empty li if (this.$productList.size() < 1) return false; // mobilemaincategory-slider exception if (this.$productModule.find('.afterNone').size() > 0) return true; // no condition swipe if (this.$productList.size() <= this.iPageBlock) return false; }, /* * ganerate swipe single dom */ generate : function() { if (this.sMode == 'single') { this.generateSingle(); } else { this.generateMulti(); } }, /* * prepare for element */ prepare : function() { var $prepare = { /* * reset element and circle */ reset : function() { $S.aElement = []; $S.aButton = []; }, /* * set target id */ setId : function() { $S.$product.attr('id', $S.sModule + '-slider-' + $S.iActive); } } $prepare.reset(); $prepare.setId(); }, /* * ganerate swipe single dom */ generateSingle : function() { // prepare this.prepare(); // make li > ul > li for (var i=0; i ul > li for (var i=0, k=1, j=0; i ul var $template = (j == 0) ? $("
    • ", { html: $("
        ", {'class': this.sGrid} ) } ) : $('
      • ', { html: $("
          ", {'class': this.sGrid} ), css: {'display': 'none'} } ); // add li > ul if (k == 1) { this.$productModule.append($template); // < 현재페이지 / 총페이지 > if (this.sPagingType !== 'number') { this.makeButton(j); } } // add li > ul > li this.$product.children('ul').children('li').eq(j).children('ul').append(this.aElement[i]); // see block if (k == this.iPageBlock) { k = 0; j++; } } if (this.sPagingType === 'number') { this.makeNumber(); } // not necessary pagenate if (i < (parseInt(this.iPageBlock) + 1)) return; // call pagenate this.makePagenate(); }, makeButton : function(iCnt) { // ECQAINT-14112 롤링 및 넘버링 타입은 '모바일 환경설정'의 기본 사양에 따라 최대 갯수 5개로 설정 if (this.sPagingType == 'rolling' || this.sPagingType == 'numbering') { this.iLimit = 5; } else if (this.sPagingType !== 'circle') { this.iLimit = 4; } var iNum = iCnt + 1, sSelected = (iCnt == 0) ? 'selected' : '', iPage = Math.ceil(iNum / this.iLimit), sLimitStyle = (iNum > this.iLimit) ? 'style="display:none"' : '', sName = this.sActiveProduct + '_page_'+iPage+'_'+iNum; if (this.sPagingType === 'fix') { var sSelected = (iCnt == 0) ? 'this' : 'other'; this.divPaginateName = 'typeList'; this.aButton.push( '
        • ' + iNum +'
        • ' ); } else if (this.sPagingType === 'numbering') { this.divPaginateName = 'typeNumber'; } else if (this.sPagingType === 'rolling') { this.divPaginateName = 'typeRoll'; this.aButton.push('
        • ' + iNum + '
        • '); } else { // circle this.divPaginateName = 'typeSwipe'; this.aButton.push( '' ); } }, /* * make fix number */ makeNumber : function() { this.divPaginateName = 'typeTotal'; sName = this.sModule+'-'+this.iActive+'_page'; this.aButton.push('1 / ' + this.iTotalPage + ''); }, /* * make pagenation */ makePagenate : function() { var sSwipeId = this.sModule + '-swipe-button-' + this.iActive; var sPaginateStyle = ''; var aBtn = []; if (this.sPagingType === 'fix') { aBtn.push('

          이전 페이지

          '); aBtn.push('
            '+this.aButton.join('')+'
          '); aBtn.push('

          다음 페이지

          '); } else if (this.sPagingType === 'numbering') { aBtn.push('

          1 / ' + this.$productList.size() + '

          '); } else if (this.sPagingType === 'rolling') { sPaginateStyle = 'position:static;'; aBtn.push('
            '+this.aButton.join('')+'
          '); } else if (this.sPagingType === 'number') { aBtn.push('

          이전 페이지

          '); aBtn.push(this.aButton.join('')); aBtn.push('

          다음 페이지

          '); } else { aBtn.push( '' ); aBtn.push( '' + this.aButton.join('') +'' ); aBtn.push( '' ); } var sPaginateForm = '
          ' + aBtn.join('') + '
          '; if ($S.bSlider === false) { this.$product.append(sPaginateForm); } }, /* * call ajax */ callAjax : function() { this.iPage++; this.setAjaxParam(); var $ajaxLoadContainer = { load : function() { var $load = '
          ', $dimmed = '
          '; $('body').append($load + $dimmed); }, remove : function() { $('body').find('div.loading, div.dimmed').remove(); } }; $.ajax({ type : "get", url : this.sParam, dataType : "json", success : function(data){ try{ if (data.rtn_code == '1000') { $(data.rtn_data.data).each(function(index, node) { // new index var newElementIndex = $S.iAjax + index; // append new element $S.$productModule.append(EC_MOBILE_UTIL.convertNode(node)); // set onerror img EC_MOBILE_UTIL.setDefaultImage(); // element setting $S.$product.find('li').eq(newElementIndex).css({ width : $(window).width() + 'px', display : 'table-cell', 'vertical-align' : 'top' }).bind('click', function(){ globalPictorlControl($S.$product); }); }); var len = data.rtn_data.data.length, currentSlider = '$' + $S.sModuleSwipe + '_slider_' + $S.iActive; // set swipe scale $S.$productModule.width($S.$productModule.width() + ($(window).width() * len)); // add ajax condition $S.iAjax += len; // stop ajax control if (len < oMobileSliderData.iSliderLimit) { $S.bAjax = false; } } else { alert('상품을 추가로 더 불러오는 과정에 문제가 발생했습니다. 지속적으로 발생할 경우 운영자에게 문의하세요.'); return false; } } catch(e) { $ajaxLoadContainer.remove(); } }, error: function(xhr,status,error){ //alert('네크워크나 상품API연동에 문제가 있습니다. 지속적으로 발생할 경우 운영자에게 문의하세요.'); return false; }, beforeSend:function(){ $ajaxLoadContainer.load(); }, complete:function() { $ajaxLoadContainer.remove(); // set swipe module length && excute next slider var currentSlider = '$' + $S.sModuleSwipe + '_slider_' + $S.iActive; eval(currentSlider + '.setLength(' + $S.iAjax + ');'); } }); }, /* * set Param */ setAjaxParam : function() { var aParam = []; aParam['cate_no'] = oMobileSliderData.iCategoryNo; aParam['page'] = this.iPage; aParam['count'] = oMobileSliderData.iSliderLimit; this.sParam = EC_MOBILE_UTIL.setAjaxParam(aParam, this.sModule); }, /* * load swipe js */ load : function() { try { var aSwipeVars = [], $swipe = document.getElementById('' + this.sModule + '-slider-' + this.iActive + ''), $now = this.$product.find('div.swipePage').find('span.now'); if (this.sPagingType !== 'circle') { this.$product.find('.typeSwipe .prev, .typeSwipe .next').show(); } // 상품의 고유한 값(상품 번호 및 카테고리 번호 등)을 지정 // 이렇게 하지 않으면 스와이프 모듈을 하나로 인식하여 처리되기 때문 var sProductInfo = ''; // try-catch로 모듈의 상품 정보를 불러와서 처리하고, 정보가 없으면 처리하지 않음 try { sProductInfo = this.$productModule.find('li:first').attr('data-param').replace(/\?/gi, '').replace(/\&\=/gi, '_'); } catch(e) { } aSwipeVars.push( '$' + this.sModuleSwipe + '_slider_' + this.iActive + ' = new SwipeClient($swipe, {' ); aSwipeVars.push( ' startSlide: ' + this.iStart + ',' ); aSwipeVars.push( ' auto: ' + this.iAutoSlideInterval + ',' ); aSwipeVars.push( ' cache: \'' + this.sCache + '\',' ); aSwipeVars.push( ' elementId: \'' + this.sModuleSwipe + '_slider_' + sProductInfo + '\',' ); aSwipeVars.push( ' callback: function(e, pos, ele, obj) {' ); aSwipeVars.push( ' if (obj.container.id == "xans-layout-mobilemaincategory-slider-0") { globalCategorySetUi(mode = "init", pos); }' ); aSwipeVars.push( ' try { if (globalPictorialLoad === true) { globalPictorialSetUi($S.$product, pos) } } catch(e) {}' ); aSwipeVars.push( ' var iSelectedPos = pos + 1;' ); aSwipeVars.push( ' if ($S.bSlider === true) { $now.text(iSelectedPos); }' ); aSwipeVars.push(this.getSwipeButtonDisplay()); aSwipeVars.push( ' }' ); aSwipeVars.push( '});' ); eval(aSwipeVars.join('')); } catch(e) { } }, getSwipeButtonDisplay : function() { var sSelected = 'selected'; var sChildSelector = ''; if (this.sPagingType === 'fix') { sSelected = 'this'; sChildSelector = ' > a'; } var sSwipeVars = ''; if (this.sPagingType === 'number') { sSwipeVars = ' $("[name^=\'' + this.sActiveProduct + '_page\'] > strong").text(iSelectedPos);' ; } else if (this.sPagingType === 'numbering') { sSwipeVars = '$(".' + this.divPaginateName + ' > p > strong").text(iSelectedPos);'; } else if (this.sPagingType === 'rolling') { sSwipeVars = ' $("[name^=\'' + this.sActiveProduct + '_page\']").removeClass(\'' + sSelected + '\');'; sSwipeVars += ' $("[name=\'' + this.sActiveProduct + '_page_1_"+iSelectedPos+"\']").addClass(\'' + sSelected + '\');'; } else { sSwipeVars = ' var iPage = pos === ' + this.iTotalPage + ' ? Math.ceil(' + this.iTotalPage + ' / $S.iLimit) : Math.ceil(iSelectedPos / $S.iLimit);' ; /* ECHOSTING-251668 show/hide 조건 삭제 sSwipeVars += ' if ((pos % $S.iLimit === 0) || (iSelectedPos % $S.iLimit === 0 || iSelectedPos === ' + this.iTotalPage + ')) {'; sSwipeVars += ' $("[name^=\'' + this.sActiveProduct + '_page\']").hide();'; sSwipeVars += ' $("[name^=\'' + this.sActiveProduct + '_page_"+iPage+"\']").show();'; sSwipeVars += ' }'; sSwipeVars += ' $("[name^=\'' + this.sActiveProduct + '_page\']' + sChildSelector + '").removeClass(\'' + sSelected + '\');'; sSwipeVars += ' $("[name=\'' + this.sActiveProduct + '_page_"+iPage+"_"+iSelectedPos+"\']' + sChildSelector + '").addClass(\'' + sSelected + '\');'; */ sSwipeVars += ' $("[name^=\'' + this.sActiveProduct + '_page\']").hide();'; sSwipeVars += ' $("[name^=\'' + this.sActiveProduct + '_page_"+iPage+"\']").show();'; sSwipeVars += ' $("[name^=\'' + this.sActiveProduct + '_page\']' + sChildSelector + '").removeClass(\'' + sSelected + '\');'; sSwipeVars += ' $("[name=\'' + this.sActiveProduct + '_page_"+iPage+"_"+iSelectedPos+"\']' + sChildSelector + '").addClass(\'' + sSelected + '\');'; } return sSwipeVars; } }; $(document).ready(function(){ sAttribute = 'ec-data-src'; if ($('img['+sAttribute+']').length > 0) { EC_lazyload(); } }); /** * IntersectionObserver와 MutationObserver를 이용한 Lazyload * @constructor */ var EC_lazyload = function() { var oConfig = { rootMargin: '0px 0px 50px 0px', threshold: 0 }; var placeholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII='; $('img['+sAttribute+']').attr('src', placeholder); /** * IntersectionObserver에 객체를 등록하는 메소드 * @type {IntersectionObserver|*} */ var oIntersection = new IntersectionObserver(function (oEntry, self) { var iEntryLength = oEntry.length; for (var i = 0; i < iEntryLength; i++) { if (oEntry[i].target.tagName !== 'IMG') { continue; } if (oEntry[i].target.hasAttribute(sAttribute) === false) { continue; } oEntry[i].target.src = placeholder; if (oEntry[i].isIntersecting) { preloadImage(oEntry[i].target); self.unobserve(oEntry[i].target); } } // 상품목록에 블럭형 레이이아웃이 존재할때만 이미지 로딩 이후 호출 if (typeof resizeContent === 'function') { resizeContent(); } }, oConfig); /** * MutationObserver에 객체를 등록하는 메소드 * @type {MutationObserver} */ var oMutation = new MutationObserver(function (oMutationElement) { var iMutationLength = oMutationElement.length; for (var i = 0 ; i < iMutationLength ; i++) { if (oMutationElement[i].addedNodes.length > 0) { oMutationElement[i].addedNodes.forEach(function (currnetValue) { registIntersection(currnetValue); }); } } }); /** * Mutation에서 검출된 객체를 Intersection으로 등록하는 메소드 * @param oParentElement */ function registIntersection(oParentElement) { if (typeof oParentElement.querySelectorAll !== 'function') { return; } var oImage = oParentElement.querySelectorAll('img['+sAttribute+']'); for (var i=0; i < oImage.length; i++) { oIntersection.observe(oImage[i]); } } /** * 실제 이미지 교체 메소드 * @param img */ function preloadImage(img) { var src = img.getAttribute(sAttribute); if (!src) return; img.src = src; img.removeAttribute(sAttribute); } var oNodeList = document.body.childNodes; var oMutationConfig = { childList: true, subtree: true }; var iNodeListLength = oNodeList.length; if (iNodeListLength === 0) { return; } for (var i = 0; i < iNodeListLength; i++) { registIntersection(oNodeList[i]); oMutation.observe(oNodeList[i], oMutationConfig); } }; /*! * Shim for MutationObserver interface * Author: Graeme Yeates (github.com/megawac) * Repository: https://github.com/megawac/MutationObserver.js * License: WTFPL V2, 2004 (wtfpl.net). * Though credit and staring the repo will make me feel pretty, you can modify and redistribute as you please. * Attempts to follow spec (https://www.w3.org/TR/dom/#mutation-observers) as closely as possible for native javascript * See https://github.com/WebKit/webkit/blob/master/Source/WebCore/dom/MutationObserver.cpp for current webkit source c++ implementation */ /** * prefix bugs: - https://bugs.webkit.org/show_bug.cgi?id=85161 - https://bugzilla.mozilla.org/show_bug.cgi?id=749920 * Don't use WebKitMutationObserver as Safari (6.0.5-6.1) use a buggy implementation */ window.MutationObserver = window.MutationObserver || (function(undefined) { "use strict"; /** * @param {function(Array., MutationObserver)} listener * @constructor */ function MutationObserver(listener) { /** * @type {Array.} * @private */ this._watched = []; /** @private */ this._listener = listener; } /** * Start a recursive timeout function to check all items being observed for mutations * @type {MutationObserver} observer * @private */ function startMutationChecker(observer) { (function check() { var mutations = observer.takeRecords(); if (mutations.length) { // fire away // calling the listener with context is not spec but currently consistent with FF and WebKit observer._listener(mutations, observer); } /** @private */ observer._timeout = setTimeout(check, MutationObserver._period); })(); } /** * Period to check for mutations (~32 times/sec) * @type {number} * @expose */ MutationObserver._period = 30 /*ms+runtime*/ ; /** * Exposed API * @expose * @final */ MutationObserver.prototype = { /** * see https://dom.spec.whatwg.org/#dom-mutationobserver-observe * not going to throw here but going to follow the current spec config sets * @param {Node|null} $target * @param {Object|null} config : MutationObserverInit configuration dictionary * @expose * @return undefined */ observe: function($target, config) { /** * Using slightly different names so closure can go ham * @type {!Object} : A custom mutation config */ var settings = { attr: !! (config.attributes || config.attributeFilter || config.attributeOldValue), // some browsers enforce that subtree must be set with childList, attributes or characterData. // We don't care as spec doesn't specify this rule. kids: !! config.childList, descendents: !! config.subtree, charData: !! (config.characterData || config.characterDataOldValue) }; var watched = this._watched; // remove already observed target element from pool for (var i = 0; i < watched.length; i++) { if (watched[i].tar === $target) watched.splice(i, 1); } if (config.attributeFilter) { /** * converts to a {key: true} dict for faster lookup * @type {Object.} */ settings.afilter = reduce(config.attributeFilter, function(a, b) { a[b] = true; return a; }, {}); } watched.push({ tar: $target, fn: createMutationSearcher($target, settings) }); // reconnect if not connected if (!this._timeout) { startMutationChecker(this); } }, /** * Finds mutations since last check and empties the "record queue" i.e. mutations will only be found once * @expose * @return {Array.} */ takeRecords: function() { var mutations = []; var watched = this._watched; for (var i = 0; i < watched.length; i++) { watched[i].fn(mutations); } return mutations; }, /** * @expose * @return undefined */ disconnect: function() { this._watched = []; // clear the stuff being observed clearTimeout(this._timeout); // ready for garbage collection /** @private */ this._timeout = null; } }; /** * Simple MutationRecord pseudoclass. No longer exposing as its not fully compliant * @param {Object} data * @return {Object} a MutationRecord */ function MutationRecord(data) { var settings = { // technically these should be on proto so hasOwnProperty will return false for non explicitly props type: null, target: null, addedNodes: [], removedNodes: [], previousSibling: null, nextSibling: null, attributeName: null, attributeNamespace: null, oldValue: null }; for (var prop in data) { if (has(settings, prop) && data[prop] !== undefined) settings[prop] = data[prop]; } return settings; } /** * Creates a func to find all the mutations * * @param {Node} $target * @param {!Object} config : A custom mutation config */ function createMutationSearcher($target, config) { /** type {Elestuct} */ var $oldstate = clone($target, config); // create the cloned datastructure /** * consumes array of mutations we can push to * * @param {Array.} mutations */ return function(mutations) { var olen = mutations.length, dirty; if (config.charData && $target.nodeType === 3 && $target.nodeValue !== $oldstate.charData) { mutations.push(new MutationRecord({ type: "characterData", target: $target, oldValue: $oldstate.charData })); } // Alright we check base level changes in attributes... easy if (config.attr && $oldstate.attr) { findAttributeMutations(mutations, $target, $oldstate.attr, config.afilter); } // check childlist or subtree for mutations if (config.kids || config.descendents) { dirty = searchSubtree(mutations, $target, $oldstate, config); } // reclone data structure if theres changes if (dirty || mutations.length !== olen) { /** type {Elestuct} */ $oldstate = clone($target, config); } }; } /* attributes + attributeFilter helpers */ // Check if the environment has the attribute bug (#4) which cause // element.attributes.style to always be null. var hasAttributeBug = document.createElement("i"); hasAttributeBug.style.top = 0; hasAttributeBug = hasAttributeBug.attributes.style.value != "null"; /** * Gets an attribute value in an environment without attribute bug * * @param {Node} el * @param {Attr} attr * @return {String} an attribute value */ function getAttributeSimple(el, attr) { // There is a potential for a warning to occur here if the attribute is a // custom attribute in IE<9 with a custom .toString() method. This is // just a warning and doesn't affect execution (see #21) return attr.value; } /** * Gets an attribute value with special hack for style attribute (see #4) * * @param {Node} el * @param {Attr} attr * @return {String} an attribute value */ function getAttributeWithStyleHack(el, attr) { // As with getAttributeSimple there is a potential warning for custom attribtues in IE7. return attr.name !== "style" ? attr.value : el.style.cssText; } var getAttributeValue = hasAttributeBug ? getAttributeSimple : getAttributeWithStyleHack; /** * fast helper to check to see if attributes object of an element has changed * doesnt handle the textnode case * * @param {Array.} mutations * @param {Node} $target * @param {Object.} $oldstate : Custom attribute clone data structure from clone * @param {Object} filter */ function findAttributeMutations(mutations, $target, $oldstate, filter) { var checked = {}; var attributes = $target.attributes; var attr; var name; var i = attributes.length; while (i--) { attr = attributes[i]; name = attr.name; if (!filter || has(filter, name)) { if (getAttributeValue($target, attr) !== $oldstate[name]) { // The pushing is redundant but gzips very nicely mutations.push(MutationRecord({ type: "attributes", target: $target, attributeName: name, oldValue: $oldstate[name], attributeNamespace: attr.namespaceURI // in ie<8 it incorrectly will return undefined })); } checked[name] = true; } } for (name in $oldstate) { if (!(checked[name])) { mutations.push(MutationRecord({ target: $target, type: "attributes", attributeName: name, oldValue: $oldstate[name] })); } } } /** * searchSubtree: array of mutations so far, element, element clone, bool * synchronous dfs comparision of two nodes * This function is applied to any observed element with childList or subtree specified * Sorry this is kind of confusing as shit, tried to comment it a bit... * codereview.stackexchange.com/questions/38351 discussion of an earlier version of this func * * @param {Array} mutations * @param {Node} $target * @param {!Object} $oldstate : A custom cloned node from clone() * @param {!Object} config : A custom mutation config */ function searchSubtree(mutations, $target, $oldstate, config) { // Track if the tree is dirty and has to be recomputed (#14). var dirty; /* * Helper to identify node rearrangment and stuff... * There is no gaurentee that the same node will be identified for both added and removed nodes * if the positions have been shuffled. * conflicts array will be emptied by end of operation */ function resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes) { // the distance between the first conflicting node and the last var distance = conflicts.length - 1; // prevents same conflict being resolved twice consider when two nodes switch places. // only one should be given a mutation event (note -~ is used as a math.ceil shorthand) var counter = -~((distance - numAddedNodes) / 2); var $cur; var oldstruct; var conflict; while ((conflict = conflicts.pop())) { $cur = $kids[conflict.i]; oldstruct = $oldkids[conflict.j]; // attempt to determine if there was node rearrangement... won't gaurentee all matches // also handles case where added/removed nodes cause nodes to be identified as conflicts if (config.kids && counter && Math.abs(conflict.i - conflict.j) >= distance) { mutations.push(MutationRecord({ type: "childList", target: node, addedNodes: [$cur], removedNodes: [$cur], // haha don't rely on this please nextSibling: $cur.nextSibling, previousSibling: $cur.previousSibling })); counter--; // found conflict } // Alright we found the resorted nodes now check for other types of mutations if (config.attr && oldstruct.attr) findAttributeMutations(mutations, $cur, oldstruct.attr, config.afilter); if (config.charData && $cur.nodeType === 3 && $cur.nodeValue !== oldstruct.charData) { mutations.push(MutationRecord({ type: "characterData", target: $cur, oldValue: oldstruct.charData })); } // now look @ subtree if (config.descendents) findMutations($cur, oldstruct); } } /** * Main worker. Finds and adds mutations if there are any * @param {Node} node * @param {!Object} old : A cloned data structure using internal clone */ function findMutations(node, old) { var $kids = node.childNodes; var $oldkids = old.kids; var klen = $kids.length; // $oldkids will be undefined for text and comment nodes var olen = $oldkids ? $oldkids.length : 0; // if (!olen && !klen) return; // both empty; clearly no changes // we delay the intialization of these for marginal performance in the expected case (actually quite signficant on large subtrees when these would be otherwise unused) // map of checked element of ids to prevent registering the same conflict twice var map; // array of potential conflicts (ie nodes that may have been re arranged) var conflicts; var id; // element id from getElementId helper var idx; // index of a moved or inserted element var oldstruct; // current and old nodes var $cur; var $old; // track the number of added nodes so we can resolve conflicts more accurately var numAddedNodes = 0; // iterate over both old and current child nodes at the same time var i = 0, j = 0; // while there is still anything left in $kids or $oldkids (same as i < $kids.length || j < $oldkids.length;) while( i < klen || j < olen ) { // current and old nodes at the indexs $cur = $kids[i]; oldstruct = $oldkids[j]; $old = oldstruct && oldstruct.node; if ($cur === $old) { // expected case - optimized for this case // check attributes as specified by config if (config.attr && oldstruct.attr) /* oldstruct.attr instead of textnode check */findAttributeMutations(mutations, $cur, oldstruct.attr, config.afilter); // check character data if node is a comment or textNode and it's being observed if (config.charData && oldstruct.charData !== undefined && $cur.nodeValue !== oldstruct.charData) { mutations.push(MutationRecord({ type: "characterData", target: $cur, oldValue: oldstruct.charData })); } // resolve conflicts; it will be undefined if there are no conflicts - otherwise an array if (conflicts) resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes); // recurse on next level of children. Avoids the recursive call when there are no children left to iterate if (config.descendents && ($cur.childNodes.length || oldstruct.kids && oldstruct.kids.length)) findMutations($cur, oldstruct); i++; j++; } else { // (uncommon case) lookahead until they are the same again or the end of children dirty = true; if (!map) { // delayed initalization (big perf benefit) map = {}; conflicts = []; } if ($cur) { // check id is in the location map otherwise do a indexOf search if (!(map[id = getElementId($cur)])) { // to prevent double checking // mark id as found map[id] = true; // custom indexOf using comparitor checking oldkids[i].node === $cur if ((idx = indexOfCustomNode($oldkids, $cur, j)) === -1) { if (config.kids) { mutations.push(MutationRecord({ type: "childList", target: node, addedNodes: [$cur], // $cur is a new node nextSibling: $cur.nextSibling, previousSibling: $cur.previousSibling })); numAddedNodes++; } } else { conflicts.push({ // add conflict i: i, j: idx }); } } i++; } if ($old && // special case: the changes may have been resolved: i and j appear congurent so we can continue using the expected case $old !== $kids[i] ) { if (!(map[id = getElementId($old)])) { map[id] = true; if ((idx = indexOf($kids, $old, i)) === -1) { if (config.kids) { mutations.push(MutationRecord({ type: "childList", target: old.node, removedNodes: [$old], nextSibling: $oldkids[j + 1], // praise no indexoutofbounds exception previousSibling: $oldkids[j - 1] })); numAddedNodes--; } } else { conflicts.push({ i: idx, j: j }); } } j++; } }// end uncommon case }// end loop // resolve any remaining conflicts if (conflicts) resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes); } findMutations($target, $oldstate); return dirty; } /** * Utility * Cones a element into a custom data structure designed for comparision. https://gist.github.com/megawac/8201012 * * @param {Node} $target * @param {!Object} config : A custom mutation config * @return {!Object} : Cloned data structure */ function clone($target, config) { var recurse = true; // set true so childList we'll always check the first level return (function copy($target) { var elestruct = { /** @type {Node} */ node: $target }; // Store current character data of target text or comment node if the config requests // those properties to be observed. if (config.charData && ($target.nodeType === 3 || $target.nodeType === 8)) { elestruct.charData = $target.nodeValue; } // its either a element, comment, doc frag or document node else { // Add attr only if subtree is specified or top level and avoid if // attributes is a document object (#13). if (config.attr && recurse && $target.nodeType === 1) { /** * clone live attribute list to an object structure {name: val} * @type {Object.} */ elestruct.attr = reduce($target.attributes, function(memo, attr) { if (!config.afilter || config.afilter[attr.name]) { memo[attr.name] = getAttributeValue($target, attr); } return memo; }, {}); } // whether we should iterate the children of $target node if (recurse && ((config.kids || config.charData) || (config.attr && config.descendents)) ) { /** @type {Array.} : Array of custom clone */ elestruct.kids = map($target.childNodes, copy); } recurse = config.descendents; } return elestruct; })($target); } /** * indexOf an element in a collection of custom nodes * * @param {NodeList} set * @param {!Object} $node : A custom cloned node * @param {number} idx : index to start the loop * @return {number} */ function indexOfCustomNode(set, $node, idx) { return indexOf(set, $node, idx, JSCompiler_renameProperty("node")); } // using a non id (eg outerHTML or nodeValue) is extremely naive and will run into issues with nodes that may appear the same like
        • var counter = 1; // don't use 0 as id (falsy) /** @const */ var expando = "mo_id"; /** * Attempt to uniquely id an element for hashing. We could optimize this for legacy browsers but it hopefully wont be called enough to be a concern * * @param {Node} $ele * @return {(string|number)} */ function getElementId($ele) { try { return $ele.id || ($ele[expando] = $ele[expando] || counter++); } catch (o_O) { // ie <8 will throw if you set an unknown property on a text node try { return $ele.nodeValue; // naive } catch (shitie) { // when text node is removed: https://gist.github.com/megawac/8355978 :( return counter++; } } } /** * **map** Apply a mapping function to each item of a set * @param {Array|NodeList} set * @param {Function} iterator */ function map(set, iterator) { var results = []; for (var index = 0; index < set.length; index++) { results[index] = iterator(set[index], index, set); } return results; } /** * **Reduce** builds up a single result from a list of values * @param {Array|NodeList|NamedNodeMap} set * @param {Function} iterator * @param {*} [memo] Initial value of the memo. */ function reduce(set, iterator, memo) { for (var index = 0; index < set.length; index++) { memo = iterator(memo, set[index], index, set); } return memo; } /** * **indexOf** find index of item in collection. * @param {Array|NodeList} set * @param {Object} item * @param {number} idx * @param {string} [prop] Property on set item to compare to item */ function indexOf(set, item, idx, prop) { for (/*idx = ~~idx*/; idx < set.length; idx++) {// start idx is always given as this is internal if ((prop ? set[idx][prop] : set[idx]) === item) return idx; } return -1; } /** * @param {Object} obj * @param {(string|number)} prop * @return {boolean} */ function has(obj, prop) { return obj[prop] !== undefined; // will be nicely inlined by gcc } // GCC hack see https://stackoverflow.com/a/23202438/1517919 function JSCompiler_renameProperty(a) { return a; } return MutationObserver; })(void 0); /** * Copyright 2016 Google Inc. All Rights Reserved. * * Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE. * * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document * */ (function(window, document) { 'use strict'; // Exits early if all IntersectionObserver and IntersectionObserverEntry // features are natively supported. if ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype) { // Minimal polyfill for Edge 15's lack of `isIntersecting` // See: https://github.com/w3c/IntersectionObserver/issues/211 if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) { Object.defineProperty(window.IntersectionObserverEntry.prototype, 'isIntersecting', { get: function () { return this.intersectionRatio > 0; } }); } return; } /** * An IntersectionObserver registry. This registry exists to hold a strong * reference to IntersectionObserver instances currently observering a target * element. Without this registry, instances without another reference may be * garbage collected. */ var registry = []; /** * Creates the global IntersectionObserverEntry constructor. * https://w3c.github.io/IntersectionObserver/#intersection-observer-entry * @param {Object} entry A dictionary of instance properties. * @constructor */ function IntersectionObserverEntry(entry) { this.time = entry.time; this.target = entry.target; this.rootBounds = entry.rootBounds; this.boundingClientRect = entry.boundingClientRect; this.intersectionRect = entry.intersectionRect || getEmptyRect(); this.isIntersecting = !!entry.intersectionRect; // Calculates the intersection ratio. var targetRect = this.boundingClientRect; var targetArea = targetRect.width * targetRect.height; var intersectionRect = this.intersectionRect; var intersectionArea = intersectionRect.width * intersectionRect.height; // Sets intersection ratio. if (targetArea) { this.intersectionRatio = intersectionArea / targetArea; } else { // If area is zero and is intersecting, sets to 1, otherwise to 0 this.intersectionRatio = this.isIntersecting ? 1 : 0; } } /** * Creates the global IntersectionObserver constructor. * https://w3c.github.io/IntersectionObserver/#intersection-observer-interface * @param {Function} callback The function to be invoked after intersection * changes have queued. The function is not invoked if the queue has * been emptied by calling the `takeRecords` method. * @param {Object=} opt_options Optional configuration options. * @constructor */ function IntersectionObserver(callback, opt_options) { var options = opt_options || {}; if (typeof callback != 'function') { throw new Error('callback must be a function'); } if (options.root && options.root.nodeType != 1) { throw new Error('root must be an Element'); } // Binds and throttles `this._checkForIntersections`. this._checkForIntersections = throttle( this._checkForIntersections.bind(this), this.THROTTLE_TIMEOUT); // Private properties. this._callback = callback; this._observationTargets = []; this._queuedEntries = []; this._rootMarginValues = this._parseRootMargin(options.rootMargin); // Public properties. this.thresholds = this._initThresholds(options.threshold); this.root = options.root || null; this.rootMargin = this._rootMarginValues.map(function(margin) { return margin.value + margin.unit; }).join(' '); } /** * The minimum interval within which the document will be checked for * intersection changes. */ IntersectionObserver.prototype.THROTTLE_TIMEOUT = 100; /** * The frequency in which the polyfill polls for intersection changes. * this can be updated on a per instance basis and must be set prior to * calling `observe` on the first target. */ IntersectionObserver.prototype.POLL_INTERVAL = null; /** * Use a mutation observer on the root element * to detect intersection changes. */ IntersectionObserver.prototype.USE_MUTATION_OBSERVER = true; /** * Starts observing a target element for intersection changes based on * the thresholds values. * @param {Element} target The DOM element to observe. */ IntersectionObserver.prototype.observe = function(target) { var isTargetAlreadyObserved = this._observationTargets.some(function(item) { return item.element == target; }); if (isTargetAlreadyObserved) { return; } if (!(target && target.nodeType == 1)) { throw new Error('target must be an Element'); } this._registerInstance(); this._observationTargets.push({element: target, entry: null}); this._monitorIntersections(); this._checkForIntersections(); }; /** * Stops observing a target element for intersection changes. * @param {Element} target The DOM element to observe. */ IntersectionObserver.prototype.unobserve = function(target) { this._observationTargets = this._observationTargets.filter(function(item) { return item.element != target; }); if (!this._observationTargets.length) { this._unmonitorIntersections(); this._unregisterInstance(); } }; /** * Stops observing all target elements for intersection changes. */ IntersectionObserver.prototype.disconnect = function() { this._observationTargets = []; this._unmonitorIntersections(); this._unregisterInstance(); }; /** * Returns any queue entries that have not yet been reported to the * callback and clears the queue. This can be used in conjunction with the * callback to obtain the absolute most up-to-date intersection information. * @return {Array} The currently queued entries. */ IntersectionObserver.prototype.takeRecords = function() { var records = this._queuedEntries.slice(); this._queuedEntries = []; return records; }; /** * Accepts the threshold value from the user configuration object and * returns a sorted array of unique threshold values. If a value is not * between 0 and 1 and error is thrown. * @private * @param {Array|number=} opt_threshold An optional threshold value or * a list of threshold values, defaulting to [0]. * @return {Array} A sorted list of unique and valid threshold values. */ IntersectionObserver.prototype._initThresholds = function(opt_threshold) { var threshold = opt_threshold || [0]; if (!Array.isArray(threshold)) threshold = [threshold]; return threshold.sort().filter(function(t, i, a) { if (typeof t != 'number' || isNaN(t) || t < 0 || t > 1) { throw new Error('threshold must be a number between 0 and 1 inclusively'); } return t !== a[i - 1]; }); }; /** * Accepts the rootMargin value from the user configuration object * and returns an array of the four margin values as an object containing * the value and unit properties. If any of the values are not properly * formatted or use a unit other than px or %, and error is thrown. * @private * @param {string=} opt_rootMargin An optional rootMargin value, * defaulting to '0px'. * @return {Array} An array of margin objects with the keys * value and unit. */ IntersectionObserver.prototype._parseRootMargin = function(opt_rootMargin) { var marginString = opt_rootMargin || '0px'; var margins = marginString.split(/\s+/).map(function(margin) { var parts = /^(-?\d*\.?\d+)(px|%)$/.exec(margin); if (!parts) { throw new Error('rootMargin must be specified in pixels or percent'); } return {value: parseFloat(parts[1]), unit: parts[2]}; }); // Handles shorthand. margins[1] = margins[1] || margins[0]; margins[2] = margins[2] || margins[0]; margins[3] = margins[3] || margins[1]; return margins; }; /** * Starts polling for intersection changes if the polling is not already * happening, and if the page's visibilty state is visible. * @private */ IntersectionObserver.prototype._monitorIntersections = function() { if (!this._monitoringIntersections) { this._monitoringIntersections = true; // If a poll interval is set, use polling instead of listening to // resize and scroll events or DOM mutations. if (this.POLL_INTERVAL) { this._monitoringInterval = setInterval( this._checkForIntersections, this.POLL_INTERVAL); } else { addEvent(window, 'resize', this._checkForIntersections, true); addEvent(document, 'scroll', this._checkForIntersections, true); if (this.USE_MUTATION_OBSERVER && 'MutationObserver' in window) { this._domObserver = new MutationObserver(this._checkForIntersections); this._domObserver.observe(document, { attributes: true, childList: true, characterData: true, subtree: true }); } } } }; /** * Stops polling for intersection changes. * @private */ IntersectionObserver.prototype._unmonitorIntersections = function() { if (this._monitoringIntersections) { this._monitoringIntersections = false; clearInterval(this._monitoringInterval); this._monitoringInterval = null; removeEvent(window, 'resize', this._checkForIntersections, true); removeEvent(document, 'scroll', this._checkForIntersections, true); if (this._domObserver) { this._domObserver.disconnect(); this._domObserver = null; } } }; /** * Scans each observation target for intersection changes and adds them * to the internal entries queue. If new entries are found, it * schedules the callback to be invoked. * @private */ IntersectionObserver.prototype._checkForIntersections = function() { var rootIsInDom = this._rootIsInDom(); var rootRect = rootIsInDom ? this._getRootRect() : getEmptyRect(); this._observationTargets.forEach(function(item) { var target = item.element; var targetRect = getBoundingClientRect(target); var rootContainsTarget = this._rootContainsTarget(target); var oldEntry = item.entry; var intersectionRect = rootIsInDom && rootContainsTarget && this._computeTargetAndRootIntersection(target, rootRect); var newEntry = item.entry = new IntersectionObserverEntry({ time: now(), target: target, boundingClientRect: targetRect, rootBounds: rootRect, intersectionRect: intersectionRect }); if (!oldEntry) { this._queuedEntries.push(newEntry); } else if (rootIsInDom && rootContainsTarget) { // If the new entry intersection ratio has crossed any of the // thresholds, add a new entry. if (this._hasCrossedThreshold(oldEntry, newEntry)) { this._queuedEntries.push(newEntry); } } else { // If the root is not in the DOM or target is not contained within // root but the previous entry for this target had an intersection, // add a new record indicating removal. if (oldEntry && oldEntry.isIntersecting) { this._queuedEntries.push(newEntry); } } }, this); if (this._queuedEntries.length) { this._callback(this.takeRecords(), this); } }; /** * Accepts a target and root rect computes the intersection between then * following the algorithm in the spec. * TODO(philipwalton): at this time clip-path is not considered. * https://w3c.github.io/IntersectionObserver/#calculate-intersection-rect-algo * @param {Element} target The target DOM element * @param {Object} rootRect The bounding rect of the root after being * expanded by the rootMargin value. * @return {?Object} The final intersection rect object or undefined if no * intersection is found. * @private */ IntersectionObserver.prototype._computeTargetAndRootIntersection = function(target, rootRect) { // If the element isn't displayed, an intersection can't happen. if (window.getComputedStyle(target).display == 'none') return; var targetRect = getBoundingClientRect(target); var intersectionRect = targetRect; var parent = getParentNode(target); var atRoot = false; while (!atRoot) { var parentRect = null; var parentComputedStyle = parent.nodeType == 1 ? window.getComputedStyle(parent) : {}; // If the parent isn't displayed, an intersection can't happen. if (parentComputedStyle.display == 'none') return; if (parent == this.root || parent == document) { atRoot = true; parentRect = rootRect; } else { // If the element has a non-visible overflow, and it's not the // or element, update the intersection rect. // Note: and cannot be clipped to a rect that's not also // the document rect, so no need to compute a new intersection. if (parent != document.body && parent != document.documentElement && parentComputedStyle.overflow != 'visible') { parentRect = getBoundingClientRect(parent); } } // If either of the above conditionals set a new parentRect, // calculate new intersection data. if (parentRect) { intersectionRect = computeRectIntersection(parentRect, intersectionRect); if (!intersectionRect) break; } parent = getParentNode(parent); } return intersectionRect; }; /** * Returns the root rect after being expanded by the rootMargin value. * @return {Object} The expanded root rect. * @private */ IntersectionObserver.prototype._getRootRect = function() { var rootRect; if (this.root) { rootRect = getBoundingClientRect(this.root); } else { // Use / instead of window since scroll bars affect size. var html = document.documentElement; var body = document.body; rootRect = { top: 0, left: 0, right: html.clientWidth || body.clientWidth, width: html.clientWidth || body.clientWidth, bottom: html.clientHeight || body.clientHeight, height: html.clientHeight || body.clientHeight }; } return this._expandRectByRootMargin(rootRect); }; /** * Accepts a rect and expands it by the rootMargin value. * @param {Object} rect The rect object to expand. * @return {Object} The expanded rect. * @private */ IntersectionObserver.prototype._expandRectByRootMargin = function(rect) { var margins = this._rootMarginValues.map(function(margin, i) { return margin.unit == 'px' ? margin.value : margin.value * (i % 2 ? rect.width : rect.height) / 100; }); var newRect = { top: rect.top - margins[0], right: rect.right + margins[1], bottom: rect.bottom + margins[2], left: rect.left - margins[3] }; newRect.width = newRect.right - newRect.left; newRect.height = newRect.bottom - newRect.top; return newRect; }; /** * Accepts an old and new entry and returns true if at least one of the * threshold values has been crossed. * @param {?IntersectionObserverEntry} oldEntry The previous entry for a * particular target element or null if no previous entry exists. * @param {IntersectionObserverEntry} newEntry The current entry for a * particular target element. * @return {boolean} Returns true if a any threshold has been crossed. * @private */ IntersectionObserver.prototype._hasCrossedThreshold = function(oldEntry, newEntry) { // To make comparing easier, an entry that has a ratio of 0 // but does not actually intersect is given a value of -1 var oldRatio = oldEntry && oldEntry.isIntersecting ? oldEntry.intersectionRatio || 0 : -1; var newRatio = newEntry.isIntersecting ? newEntry.intersectionRatio || 0 : -1; // Ignore unchanged ratios if (oldRatio === newRatio) return; for (var i = 0; i < this.thresholds.length; i++) { var threshold = this.thresholds[i]; // Return true if an entry matches a threshold or if the new ratio // and the old ratio are on the opposite sides of a threshold. if (threshold == oldRatio || threshold == newRatio || threshold < oldRatio !== threshold < newRatio) { return true; } } }; /** * Returns whether or not the root element is an element and is in the DOM. * @return {boolean} True if the root element is an element and is in the DOM. * @private */ IntersectionObserver.prototype._rootIsInDom = function() { return !this.root || containsDeep(document, this.root); }; /** * Returns whether or not the target element is a child of root. * @param {Element} target The target element to check. * @return {boolean} True if the target element is a child of root. * @private */ IntersectionObserver.prototype._rootContainsTarget = function(target) { return containsDeep(this.root || document, target); }; /** * Adds the instance to the global IntersectionObserver registry if it isn't * already present. * @private */ IntersectionObserver.prototype._registerInstance = function() { if (registry.indexOf(this) < 0) { registry.push(this); } }; /** * Removes the instance from the global IntersectionObserver registry. * @private */ IntersectionObserver.prototype._unregisterInstance = function() { var index = registry.indexOf(this); if (index != -1) registry.splice(index, 1); }; /** * Returns the result of the performance.now() method or null in browsers * that don't support the API. * @return {number} The elapsed time since the page was requested. */ function now() { return window.performance && performance.now && performance.now(); } /** * Throttles a function and delays its executiong, so it's only called at most * once within a given time period. * @param {Function} fn The function to throttle. * @param {number} timeout The amount of time that must pass before the * function can be called again. * @return {Function} The throttled function. */ function throttle(fn, timeout) { var timer = null; return function () { if (!timer) { timer = setTimeout(function() { fn(); timer = null; }, timeout); } }; } /** * Adds an event handler to a DOM node ensuring cross-browser compatibility. * @param {Node} node The DOM node to add the event handler to. * @param {string} event The event name. * @param {Function} fn The event handler to add. * @param {boolean} opt_useCapture Optionally adds the even to the capture * phase. Note: this only works in modern browsers. */ function addEvent(node, event, fn, opt_useCapture) { if (typeof node.addEventListener == 'function') { node.addEventListener(event, fn, opt_useCapture || false); } else if (typeof node.attachEvent == 'function') { node.attachEvent('on' + event, fn); } } /** * Removes a previously added event handler from a DOM node. * @param {Node} node The DOM node to remove the event handler from. * @param {string} event The event name. * @param {Function} fn The event handler to remove. * @param {boolean} opt_useCapture If the event handler was added with this * flag set to true, it should be set to true here in order to remove it. */ function removeEvent(node, event, fn, opt_useCapture) { if (typeof node.removeEventListener == 'function') { node.removeEventListener(event, fn, opt_useCapture || false); } else if (typeof node.detatchEvent == 'function') { node.detatchEvent('on' + event, fn); } } /** * Returns the intersection between two rect objects. * @param {Object} rect1 The first rect. * @param {Object} rect2 The second rect. * @return {?Object} The intersection rect or undefined if no intersection * is found. */ function computeRectIntersection(rect1, rect2) { var top = Math.max(rect1.top, rect2.top); var bottom = Math.min(rect1.bottom, rect2.bottom); var left = Math.max(rect1.left, rect2.left); var right = Math.min(rect1.right, rect2.right); var width = right - left; var height = bottom - top; return (width >= 0 && height >= 0) && { top: top, bottom: bottom, left: left, right: right, width: width, height: height }; } /** * Shims the native getBoundingClientRect for compatibility with older IE. * @param {Element} el The element whose bounding rect to get. * @return {Object} The (possibly shimmed) rect of the element. */ function getBoundingClientRect(el) { var rect; try { rect = el.getBoundingClientRect(); } catch (err) { // Ignore Windows 7 IE11 "Unspecified error" // https://github.com/w3c/IntersectionObserver/pull/205 } if (!rect) return getEmptyRect(); // Older IE if (!(rect.width && rect.height)) { rect = { top: rect.top, right: rect.right, bottom: rect.bottom, left: rect.left, width: rect.right - rect.left, height: rect.bottom - rect.top }; } return rect; } /** * Returns an empty rect object. An empty rect is returned when an element * is not in the DOM. * @return {Object} The empty rect. */ function getEmptyRect() { return { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 }; } /** * Checks to see if a parent element contains a child elemnt (including inside * shadow DOM). * @param {Node} parent The parent element. * @param {Node} child The child element. * @return {boolean} True if the parent node contains the child node. */ function containsDeep(parent, child) { var node = child; while (node) { if (node == parent) return true; node = getParentNode(node); } return false; } /** * Gets the parent node of an element or its host element if the parent node * is a shadow root. * @param {Node} node The node whose parent to get. * @return {Node|null} The parent node or null if no parent exists. */ function getParentNode(node) { var parent = node.parentNode; if (parent && parent.nodeType == 11 && parent.host) { // If the parent is a shadow root, return the host element. return parent.host; } return parent; } // Exposes the constructors globally. window.IntersectionObserver = IntersectionObserver; window.IntersectionObserverEntry = IntersectionObserverEntry; }(window, document)); if (window.NodeList && !NodeList.prototype.forEach) { NodeList.prototype.forEach = function (callback, thisArg) { thisArg = thisArg || window; for (var i = 0; i < this.length; i++) { callback.call(thisArg, this[i], i, this); } }; } var SMART_BANNER_DEFAULT = { /** * ECHOSTING-331346 : 프론트화면에서 스마트배너 갱신시 화면 리로드 * @returns {boolean} */ reloadFrontPage: function () { addEventListener('message', function(e) { if(e.origin.indexOf(EC_FRONT_JS_CONFIG_MANAGE.sDefaultAppDomain) < 0){ return false; } var jsonData = JSON.parse(e.data); if(jsonData == '' || jsonData.type == '') { return false; } if(jsonData.type == 'frontReload'){ window.location.reload(); return true; } }, false); } }; $(document).ready(function () { try { // 스마트배너 모듈명이 존재하는지 확인 var smartBannerModuleCount = $("div[module*='smart-banner-admin'],div[app4you-smart-banner*='smart-banner-admin']").length; if (!smartBannerModuleCount) { return false; } // SDK 가 로드되지 않은경우 필요값 설정 if(typeof CAFE24API == "undefined") { CAFE24API = { MALL_ID: EC_FRONT_JS_CONFIG_MANAGE.sMallId, SHOP_NO: EC_SDE_SHOP_NUM } } // 스마트배너 모듈명이 존재할경우 ScriptTag Load var defaultAppScripts = document.createElement("script"); defaultAppScripts.type = "text/javascript"; defaultAppScripts.src = EC_FRONT_JS_CONFIG_MANAGE.sSmartBannerScriptUrl; $("head").append(defaultAppScripts); // ECHOSTING-331346 : 프론트화면에서 스마트배너 갱신시 화면 리로드 SMART_BANNER_DEFAULT.reloadFrontPage(); } catch (e) { if (typeof(e) == 'object' && e.stack && window.console) { console.log(e); } } }); CAPP_SHOP_FRONT_COMMON_UTIL = { findTargetFrame : function() { //팝업창 일경우에는 바로 opener를 반환 if (CAPP_SHOP_FRONT_COMMON_UTIL.isPopupFromThisShopFront() === true) { return window.opener; } try { var bIsIframe = false; var sUrl = document.location.pathname + document.location.search; //parent의 프레임내용에서 현재주소와 동일 url을 가진 아이프레임이 있다면 아이프레임에서 실행된것으로 판단하고 parent를 반환 $(parent.document).find('iframe').each(function() { if (sUrl === $(this).attr('src')) { bIsIframe = true; return false; }; }); if (bIsIframe === true) { return parent; } } catch(e) {} //그 이외(일반페이지, 프레임셋)에서는 현재페이지에서 이동되는것으로 함 return document; }, /** * 기존 코드와의 호환성 때문에 남겨둠 * @return bool * @deprecated */ isAdminOpener : function() { return this.isPopupFromThisShopFront(); }, /** * 현재 창이 동일 쇼핑몰 내의 프론트에서 열려진 팝업창인지 리턴 * @return bool 동일 쇼핑몰 내의 프론트에서 열려진 팝업창이면 true, 아니면 false */ isPopupFromThisShopFront : function() { try { // 팝업창이 아니면 false 리턴 if (window.opener === null) { return false; } // 현재 창의 도메인과 opener의 도메인이 다르면 false 리턴 if (window.location.host !== window.opener.location.host) { return false; } // 어드민으로부터 열려진 경우 false 리턴 var regAdminUrl = /^(\/admin\/php\/|\/disp\/admin\/)/; if (regAdminUrl.test(window.opener.location.pathname) === true) { return false; } // 프론트로부터 열려진 경우이므로 true 리턴 return true; } catch (e) { // window.opener에 접근 불가능한 케이스는 이미 본 창이 닫혔거나 도메인이 다른 것이므로 false 리턴 return false; } }, /** * url에서 파라미터 가져오기 * @param string name 파라미터명 * @return string 파라미터 값 */ getParameterByName : function (name) { name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); var regexS = "[\\?&]" + name + "=([^&#]*)"; var regex = new RegExp(regexS); var results = regex.exec(window.location.href); if (results == null) { return ''; } else { return decodeURIComponent(results[1].replace(/\+/g, " ")); } }, historyBack : function(sMsg) { if (typeof(sMsg) !== 'undefined' && sMsg !== '') { alert(sMsg); } if (this.isPopupFromThisShopFront() === true) { opener = window; window.close(); } else { history.back(); } } }; document.oncontextmenu = function(){ return false; }; document.ondragstart = function(){ return false; }; document.onselectstart = function(event) { try { if (event.srcElement && event.srcElement.tagName == 'INPUT' && event.srcElement.value) { return true; } } catch (e) { return false; } return false; }; document.onkeydown = function(){ if((event.ctrlKey == true && (event.keyCode == 78 || event.keyCode == 82 || event.keyCode == 83)) || (event.keyCode >= 112 && event.keyCode <= 123)) { event.keyCode = 0; event.cancelBubble = true; event.returnValue = false; return false; } }; /** * 접속통계 & 실시간접속통계 */ $(document).ready(function(){ // 이미 weblog.js 실행 되었을 경우 종료 if ($('#log_realtime').length > 0) { return; } /* * QueryString에서 디버그 표시 제거 */ function stripDebug(sLocation) { if (typeof sLocation != 'string') return ''; sLocation = sLocation.replace(/^d[=]*[\d]*[&]*$/, ''); sLocation = sLocation.replace(/^d[=]*[\d]*[&]/, ''); sLocation = sLocation.replace(/(&d&|&d[=]*[\d]*[&]*)/, '&'); return sLocation; } // 벤트 몰이 아닐 경우에만 V3(IFrame)을 로드합니다. // @date 190117 // @date 191217 - 이벤트에도 V3 상시 적재로 변경. //if (EC_FRONT_JS_CONFIG_MANAGE.sWebLogEventFlag == "F") //{ // T 일 경우 IFRAME 을 노출하지 않는다. if (EC_FRONT_JS_CONFIG_MANAGE.sWebLogOffFlag == "F") { if (window.self == window.top) { var rloc = escape(document.location); var rref = escape(document.referrer); } else { var rloc = (document.location).pathname; var rref = ''; } // realconn & Ad aggregation var _aPrs = new Array(); _sUserQs = window.location.search.substring(1); _sUserQs = stripDebug(_sUserQs); _aPrs[0] = 'rloc=' + rloc; _aPrs[1] = 'rref=' + rref; _aPrs[2] = 'udim=' + window.screen.width + '*' + window.screen.height; _aPrs[3] = 'rserv=' + aLogData.log_server2; _aPrs[4] = 'cid=' + eclog.getCid(); _aPrs[5] = 'role_path=' + $('meta[name="path_role"]').attr('content'); _aPrs[6] = 'stype=' + aLogData.stype; _aPrs[7] = 'shop_no=' + aLogData.shop_no; _aPrs[8] = 'lang=' + aLogData.lang; _aPrs[9] = 'ver=' + aLogData.ver; // 모바일웹일 경우 추가 파라미터 생성 var _sMobilePrs = ''; if (mobileWeb === true) _sMobilePrs = '&mobile=T&mobile_ver=new'; _sUrlQs = _sUserQs + '&' + _aPrs.join('&') + _sMobilePrs; var _sUrlFull = '/exec/front/eclog/main/?' + _sUrlQs; var node = document.createElement('iframe'); node.setAttribute('src', _sUrlFull); node.setAttribute('id', 'log_realtime'); document.body.appendChild(node); $('#log_realtime').hide(); } // eclog2.0, eclog1.9 var sTime = new Date().getTime();//ECHOSTING-54575 // 접속통계 서버값이 있다면 weblog.js 호출 if (aLogData.log_server1 != null && aLogData.log_server1 != '') { var sScriptSrc = '//' + aLogData.log_server1 + '/weblog.js?uid=' + aLogData.mid + '&uname=' + aLogData.mid + '&r_ref=' + document.referrer + '&shop_no=' + aLogData.shop_no; if (mobileWeb === true) sScriptSrc += '&cafe_ec=mobile'; sScriptSrc += '&t=' + sTime;//ECHOSTING-54575 var node = document.createElement('script'); node.setAttribute('type', 'text/javascript'); node.setAttribute('src', sScriptSrc); node.setAttribute('id', 'log_script'); document.body.appendChild(node); } }); /** * 쇼핑몰 금액 라이브러리 */ var SHOP_PRICE = { /** * iShopNo 쇼핑몰의 결제화폐에 맞게 리턴합니다. * @param float fPrice 금액 * @param bool bIsNumberFormat number_format 적용 유무 * @param int iShopNo 쇼핑몰번호 * @return float|string */ toShopPrice: function(fPrice, bIsNumberFormat, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; // 결제화폐 정보 var aCurrencyInfo = SHOP_CURRENCY_INFO[iShopNo].aShopCurrencyInfo; return SHOP_PRICE.toPrice(fPrice, aCurrencyInfo, bIsNumberFormat); }, /** * iShopNo 쇼핑몰의 참조화폐에 맞게 리턴합니다. * @param float fPrice 금액 * @param bool bIsNumberFormat number_format 적용 유무 * @param int iShopNo 쇼핑몰번호 * @return float|string */ toShopSubPrice: function(fPrice, bIsNumberFormat, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; // 참조화폐 정보 var aSubCurrencyInfo = SHOP_CURRENCY_INFO[iShopNo].aShopSubCurrencyInfo; if ( ! aSubCurrencyInfo) { // 참조화폐가 없으면 return ''; } else { // 결제화폐 정보 var aCurrencyInfo = SHOP_CURRENCY_INFO[iShopNo].aShopCurrencyInfo; if (aSubCurrencyInfo.currency_code === aCurrencyInfo.currency_code) { // 결제화폐와 참조화폐가 동일하면 return ''; } else { return SHOP_PRICE.toPrice(fPrice, aSubCurrencyInfo, bIsNumberFormat); } } }, /** * 쇼핑몰의 기준화폐에 맞게 리턴합니다. * @param float fPrice 금액 * @param bool bIsNumberFormat number_format 적용 유무 * @param int iShopNo 쇼핑몰번호 * @return float */ toBasePrice: function(fPrice, bIsNumberFormat, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; // 기준화폐 정보 var aBaseCurrencyInfo = SHOP_CURRENCY_INFO[iShopNo].aBaseCurrencyInfo; return SHOP_PRICE.toPrice(fPrice, aBaseCurrencyInfo, bIsNumberFormat); }, /** * 결제화폐 금액을 참조화폐 금액으로 변환하여 리턴합니다. * @param float fPrice 금액 * @param bool bIsNumberFormat number_format 적용 유무 * @param int iShopNo 쇼핑몰번호 * @return float 참조화폐 금액 */ shopPriceToSubPrice: function(fPrice, bIsNumberFormat, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; // 결제화폐 금액 => 참조화폐 금액 fPrice = fPrice * (SHOP_CURRENCY_INFO[iShopNo].fExchangeSubRate || 0); return SHOP_PRICE.toShopSubPrice(fPrice, bIsNumberFormat, iShopNo); }, /** * 결제화폐 대비 기준화폐 환율 리턴 * @param int iShopNo 쇼핑몰번호 * @return float 결제화폐 대비 기준화폐 환율 */ getRate: function(iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; return SHOP_CURRENCY_INFO[iShopNo].fExchangeRate; }, /** * 결제화폐 대비 참조화폐 환율 리턴 * @param int iShopNo 쇼핑몰번호 * @return float 결제화폐 대비 참조화폐 환율 (참조화폐가 없는 경우 null을 리턴합니다.) */ getSubRate: function(iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; return SHOP_CURRENCY_INFO[iShopNo].fExchangeSubRate;; }, /** * 금액을 원하는 화폐코드의 제약조건(소수점 절삭)에 맞춰 리턴합니다. * @param float fPrice 금액 * @param string aCurrencyInfo 원하는 화폐의 화폐 정보 * @param bool bIsNumberFormat number_format 적용 유무 * @return float|string */ toPrice: function(fPrice, aCurrencyInfo, bIsNumberFormat) { // 소수점 아래 절삭 var iPow = Math.pow(10, aCurrencyInfo['decimal_place']); fPrice = fPrice * iPow; if (aCurrencyInfo['round_method_type'] === 'F') { fPrice = Math.floor(fPrice); } else if (aCurrencyInfo['round_method_type'] === 'C') { fPrice = Math.ceil(fPrice); } else { fPrice = Math.round(fPrice); } fPrice = fPrice / iPow; if ( ! fPrice) { // 가격이 없는 경우 return 0; } else if (bIsNumberFormat === true) { // 3자리씩 ,로 끊어서 리턴 var sPrice = fPrice.toFixed(aCurrencyInfo['decimal_place']); var regexp = /^(-?[0-9]+)([0-9]{3})($|\.|,)/; while (regexp.test(sPrice)) { sPrice = sPrice.replace(regexp, "$1,$2$3"); } return sPrice; } else { // 숫자만 리턴 return fPrice; } } }; /** * 화폐 포맷 */ var SHOP_CURRENCY_FORMAT = { /** * 어드민 페이지인지 * @var bool */ _bIsAdmin: /^\/(admin\/php|disp\/admin|exec\/admin)\//.test(location.pathname) ? true : false, /** * iShopNo 쇼핑몰의 결제화폐 포맷을 리턴합니다. * @param int iShopNo 쇼핑몰번호 * @return array head,tail */ getShopCurrencyFormat: function(iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; // 결제화폐 코드 var sCurrencyCode = SHOP_CURRENCY_INFO[iShopNo].aShopCurrencyInfo.currency_code; if (SHOP_CURRENCY_FORMAT._bIsAdmin === true) { // 어드민 // 기준화폐 코드 var sBaseCurrencyCode = SHOP_CURRENCY_INFO[iShopNo].aBaseCurrencyInfo.currency_code; if (sCurrencyCode === sBaseCurrencyCode) { // 결제화폐와 기준화폐가 동일한 경우 return { 'head': '', 'tail': '' }; } else { return { 'head': sCurrencyCode + ' ', 'tail': '' }; } } else { // 프론트 return SHOP_CURRENCY_INFO[iShopNo].aFrontCurrencyFormat; } }, /** * iShopNo 쇼핑몰의 참조화폐의 포맷을 리턴합니다. * @param int iShopNo 쇼핑몰번호 * @return array head,tail */ getShopSubCurrencyFormat: function(iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; // 참조화폐 정보 var aSubCurrencyInfo = SHOP_CURRENCY_INFO[iShopNo].aShopSubCurrencyInfo; if ( ! aSubCurrencyInfo) { // 참조화폐가 없으면 return { 'head': '', 'tail': '' }; } else if (SHOP_CURRENCY_FORMAT._bIsAdmin === true) { // 어드민 return { 'head': '(' + aSubCurrencyInfo.currency_code + ' ', 'tail': ')' }; } else { // 프론트 return SHOP_CURRENCY_INFO[iShopNo].aFrontSubCurrencyFormat; } }, /** * 쇼핑몰의 기준화폐의 포맷을 리턴합니다. * @param int iShopNo 쇼핑몰번호 * @return array head,tail */ getBaseCurrencyFormat: function(iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; // 기준화폐 코드 var sBaseCurrencyCode = SHOP_CURRENCY_INFO[iShopNo].aBaseCurrencyInfo.currency_code; // 결제화폐 코드 var sCurrencyCode = SHOP_CURRENCY_INFO[iShopNo].aShopCurrencyInfo.currency_code; if (sCurrencyCode === sBaseCurrencyCode) { // 기준화폐와 결제화폐가 동일하면 return { 'head': '', 'tail': '' }; } else { // 어드민 return { 'head': '(' + sBaseCurrencyCode + ' ', 'tail': ')' }; } }, /** * 금액 입력란 화폐 포맷용 head,tail * @param int iShopNo 쇼핑몰번호 * @return array head,tail */ getInputFormat: function(iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var sCurrencyCode = SHOP_CURRENCY_INFO[iShopNo].aShopCurrencyInfo; // 멀티쇼핑몰이 아니고 단위가 '원화'인 경우 if (SHOP.isMultiShop() === false && sCurrencyCode === 'KRW') { return { 'head': '', 'tail': '원' }; } else { return { 'head': '', 'tail': sCurrencyCode }; } }, /** * 해당몰 결제 화폐 코드 반환 * ECHOSTING-266141 대응 * 국문 기본몰 일 경우에는 화폐코드가 아닌 '원' 으로 반환 * * @param int iShopNo 쇼핑몰번호 * @return string currency_code */ getCurrencyCode: function(iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var sCurrencyCode = SHOP_CURRENCY_INFO[iShopNo].aShopCurrencyInfo.currency_code; // 멀티쇼핑몰이 아니고 단위가 '원화'인 경우 if (SHOP.isMultiShop() === false && sCurrencyCode === 'KRW') { return '원'; } else { return sCurrencyCode } } }; /** * 금액 포맷 */ var SHOP_PRICE_FORMAT = { /** * iShopNo 쇼핑몰의 결제화폐에 맞도록 하고 포맷팅하여 리턴합니다. * @param float fPrice 금액 * @param int iShopNo 쇼핑몰번호 * @return string */ toShopPrice: function(fPrice, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var aFormat = SHOP_CURRENCY_FORMAT.getShopCurrencyFormat(iShopNo); var sPrice = SHOP_PRICE.toShopPrice(fPrice, true, iShopNo); return aFormat.head + sPrice + aFormat.tail; }, /** * iShopNo 쇼핑몰의 참조화폐에 맞도록 하고 포맷팅하여 리턴합니다. * @param float fPrice 금액 * @param int iShopNo 쇼핑몰번호 * @return string */ toShopSubPrice: function(fPrice, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var aFormat = SHOP_CURRENCY_FORMAT.getShopSubCurrencyFormat(iShopNo); var sPrice = SHOP_PRICE.toShopSubPrice(fPrice, true, iShopNo); return aFormat.head + sPrice + aFormat.tail; }, /** * 쇼핑몰의 기준화폐에 맞도록 하고 포맷팅하여 리턴합니다. * @param float fPrice 금액 * @param int iShopNo 쇼핑몰번호 * @return string */ toBasePrice: function(fPrice, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var aFormat = SHOP_CURRENCY_FORMAT.getBaseCurrencyFormat(iShopNo); var sPrice = SHOP_PRICE.toBasePrice(fPrice, true, iShopNo); return aFormat.head + sPrice + aFormat.tail; }, /** * 결제화폐 금액을 참조화폐 금액으로 변환하고 포맷팅하여 리턴합니다. * @param float fPrice 금액 * @param int iShopNo 쇼핑몰번호 * @return string */ shopPriceToSubPrice: function(fPrice, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var aFormat = SHOP_CURRENCY_FORMAT.getShopSubCurrencyFormat(iShopNo); var sPrice = SHOP_PRICE.shopPriceToSubPrice(fPrice, true, iShopNo); return aFormat.head + sPrice + aFormat.tail; }, /** * 금액을 적립금 단위 명칭 설정에 따라 반환 * @param float fPrice 금액 * @return float|string */ toShopMileagePrice: function (fPrice, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var sPrice = SHOP_PRICE.toShopPrice(fPrice, true, iShopNo); if (typeof sMileageUnit != 'undefined' && $.trim(sMileageUnit) != '') { sConvertMileageUnit = sMileageUnit.replace('[:PRICE:]', sPrice); return sConvertMileageUnit; } else { return SHOP_PRICE_FORMAT.toShopPrice(fPrice); } }, /** * 금액을 예치금 단위 명칭 설정에 따라 반환 * @param float fPrice 금액 * @return float|string */ toShopDepositPrice: function (fPrice, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var sPrice = SHOP_PRICE.toShopPrice(fPrice, true, iShopNo); if (typeof sDepositUnit != 'undefined' || $.trim(sDepositUnit) != '') { return sPrice + sDepositUnit; } else { return SHOP_PRICE_FORMAT.toShopPrice(fPrice); } }, /** * 금액을 부가결제수단(통합포인트) 단위 명칭 설정에 따라 반환 * @param float fPrice 금액 * @return float|string */ toShopAddpaymentPrice: function (fPrice, sAddpaymentUnit, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var sPrice = SHOP_PRICE.toShopPrice(fPrice, true, iShopNo); if (typeof sDepositUnit != 'undefined' || $.trim(sDepositUnit) != '') { return sPrice + sAddpaymentUnit; } else { return SHOP_PRICE_FORMAT.toShopPrice(fPrice); } }, /** * 포맷을 제외한 금액정보만 리턴합니다. * @param {string} sFormattedPrice * @returns {string} */ detachFormat: function(sFormattedPrice) { if (typeof sFormattedPrice === 'undefined' || sFormattedPrice === null) { return '0'; } var sPattern = /[0-9.]/; var sPrice = ''; for (var i = 0; i < sFormattedPrice.length; i++) { if (sPattern.test(sFormattedPrice[i])) { sPrice += sFormattedPrice[i]; } } return sPrice; } }; var SHOP_PRICE_UTIL = { /** * iShopNo 쇼핑몰의 결제화폐 금액 입력폼으로 만듭니다. * @param Element elem 입력폼 * @param bool bUseMinus 마이너스 입력 사용 여부 */ toShopPriceInput: function(elem, iShopNo, bUseMinus) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var iDecimalPlace = SHOP_CURRENCY_INFO[iShopNo].aShopCurrencyInfo.decimal_place; bUseMinus ? SHOP_PRICE_UTIL._toPriceInput(elem, iDecimalPlace, bUseMinus) : SHOP_PRICE_UTIL._toPriceInput(elem, iDecimalPlace); }, /** * iShopNo 쇼핑몰의 참조화폐 금액 입력폼으로 만듭니다. * @param Element elem 입력폼 */ toShopSubPriceInput: function(elem, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var iDecimalPlace = SHOP_CURRENCY_INFO[iShopNo].aShopSubCurrencyInfo.decimal_place; SHOP_PRICE_UTIL._toPriceInput(elem, iDecimalPlace); }, /** * iShopNo 쇼핑몰의 기준화폐 금액 입력폼으로 만듭니다. * @param Element elem 입력폼 */ toBasePriceInput: function(elem, iShopNo) { iShopNo = parseInt(iShopNo) || EC_SDE_SHOP_NUM; var iDecimalPlace = SHOP_CURRENCY_INFO[iShopNo].aBaseCurrencyInfo.decimal_place; SHOP_PRICE_UTIL._toPriceInput(elem, iDecimalPlace); }, /** * 소수점 iDecimalPlace까지만 입력 가능하도록 처리 * @param Element elem 입력폼 * @param int iDecimalPlace 허용 소수점 * @param bool bUseMinus 마이너스 입력 사용 여부 */ _toPriceInput: function(elem, iDecimalPlace, bUseMinus) { attachEvent(elem, 'keyup', function(e) { e = e || window.event; bUseMinus ? replaceToMinusPrice(e.srcElement) : replaceToPrice(e.srcElement); }); attachEvent(elem, 'blur', function(e) { e = e || window.event; bUseMinus ? replaceToMinusPrice(e.srcElement) : replaceToPrice(e.srcElement); }); // 추가금액에서 마이너스를 입력받기 위해 사용 function replaceToMinusPrice(target) { var value = target.value; var regExpTest = new RegExp('^[0-9]*' + (iDecimalPlace ? '' : '\\.[0-9]{0, ' + iDecimalPlace + '}' ) + '$'); if (regExpTest.test(value) === false) { value = value.replace(/[^0-9.|\-]/g, ''); if (parseInt(iDecimalPlace)) { value = value.replace(/^([0-9]+\.[0-9]+)\.+.*$/, '$1'); value = value.replace(new RegExp('(\\.[0-9]{' + iDecimalPlace + '})[0-9]*$'), '$1'); } else { value = value.replace(/[^(0-9|\-)]/g, ''); } target.value = value; } } function replaceToPrice(target) { var value = target.value; var regExpTest = new RegExp('^[0-9]*' + (iDecimalPlace ? '' : '\\.[0-9]{0, ' + iDecimalPlace + '}' ) + '$'); if (regExpTest.test(value) === false) { value = value.replace(/[^0-9.]/g, ''); if (parseInt(iDecimalPlace)) { value = value.replace(/^([0-9]+\.[0-9]+)\.+.*$/, '$1'); value = value.replace(new RegExp('(\\.[0-9]{' + iDecimalPlace + '})[0-9]*$'), '$1'); } else { value = value.replace(/\.+[0-9]*$/, ''); } target.value = value; } } function attachEvent(elem, sEventName, fn) { if ( elem.addEventListener ) { elem.addEventListener( sEventName, fn, false ); } else if ( elem.attachEvent ) { elem.attachEvent( "on" + sEventName, fn ); } } } }; if (window.jQuery !== undefined) { $.fn.extend({ toShopPriceInput : function(iShopNo) { return this.each(function(){ var iElementShopNo = $(this).data('shop_no') || iShopNo; SHOP_PRICE_UTIL.toShopPriceInput(this, iElementShopNo); }); }, toShopSubPriceInput : function(iShopNo) { return this.each(function(){ var iElementShopNo = $(this).data('shop_no') || iShopNo; SHOP_PRICE_UTIL.toShopSubPriceInput(this, iElementShopNo); }); }, toBasePriceInput : function(iShopNo) { return this.each(function(){ var iElementShopNo = $(this).data('shop_no') || iShopNo; SHOP_PRICE_UTIL.toBasePriceInput(this, iElementShopNo); }); } }); } (function(window){ window.htmlentities = { /** * Converts a string to its html characters completely. * * @param {String} str String with unescaped HTML characters **/ encode : function(str) { var buf = []; for (var i=str.length-1;i>=0;i--) { buf.unshift(['&#', str[i].charCodeAt(), ';'].join('')); } return buf.join(''); }, /** * Converts an html characterSet into its original character. * * @param {String} str htmlSet entities **/ decode : function(str) { return str.replace(/&#(\d+);/g, function(match, dec) { return String.fromCharCode(dec); }); } }; })(window); /** * 비동기식 데이터 */ var CAPP_ASYNC_METHODS = { DEBUG: false, IS_LOGIN: (document.cookie.match(/(?:^| |;)iscache=F/) ? true : false), EC_PATH_ROLE: $('meta[name="path_role"]').attr('content') || '', aDatasetList: [], $xansMyshopMain: $('.xans-myshop-main'), init : function() { var bDebug = CAPP_ASYNC_METHODS.DEBUG; var aUseModules = []; var aNoCachedModules = []; $(CAPP_ASYNC_METHODS.aDatasetList).each(function(){ var sKey = this; var oTarget = CAPP_ASYNC_METHODS[sKey]; if (bDebug) { console.log(sKey); } var bIsUse = oTarget.isUse(); if (bDebug) { console.log(' isUse() : ' + bIsUse); } if (bIsUse === true) { aUseModules.push(sKey); if (oTarget.restoreCache === undefined || oTarget.restoreCache() === false) { if (bDebug) { console.log(' restoreCache() : true'); } aNoCachedModules.push(sKey); } } }); if (aNoCachedModules.length > 0) { var sEditor = ''; try { if (bEditor === true) { // 에디터에서 접근했을 경우 임의의 상품 지정 sEditor = '&PREVIEW_SDE=1'; } } catch(e) { } var sPathRole = '&path_role=' + CAPP_ASYNC_METHODS.EC_PATH_ROLE; $.ajax( { url : '/exec/front/manage/async?module=' + aNoCachedModules.join(',') + sEditor + sPathRole, dataType : 'json', success : function(aData) { CAPP_ASYNC_METHODS.setData(aData, aUseModules); } }); } else { CAPP_ASYNC_METHODS.setData({}, aUseModules); } }, setData : function(aData, aUseModules) { aData = aData || {}; $(aUseModules).each(function(){ var sKey = this; var oTarget = CAPP_ASYNC_METHODS[sKey]; if (oTarget.setData !== undefined && aData.hasOwnProperty(sKey) === true) { oTarget.setData(aData[sKey]); } if (oTarget.execute !== undefined) { oTarget.execute(); } }); }, _getCookie: function(sCookieName) { var re = new RegExp('(?:^| |;)' + sCookieName + '=([^;]+)'); var aCookieValue = document.cookie.match(re); return aCookieValue ? aCookieValue[1] : null; } }; /** * 비동기식 데이터 - 회원 정보 */ CAPP_ASYNC_METHODS.aDatasetList.push('member'); CAPP_ASYNC_METHODS.member = { __sEncryptedString: null, __isAdult: 'F', // 회원 데이터 __sMemberId: null, __sName: null, __sNickName: null, __sGroupName: null, __sEmail: null, __sPhone: null, __sCellphone: null, __sBirthday: null, __sGroupNo: null, __sBoardWriteName: null, __sAdditionalInformation: null, __sCreatedDate: null, isUse: function() { if (CAPP_ASYNC_METHODS.IS_LOGIN === true) { if ($('.xans-layout-statelogon, .xans-layout-logon').length > 0) { return true; } if (CAPP_ASYNC_METHODS.recent.isUse() === true && typeof(EC_FRONT_JS_CONFIG_SHOP) !== 'undefined' && EC_FRONT_JS_CONFIG_SHOP.adult19Warning === 'T') { return true; } if ( typeof EC_APPSCRIPT_SDK_DATA != "undefined" && jQuery.inArray('customer', EC_APPSCRIPT_SDK_DATA ) > -1 ) { return true; } } else { // 비 로그인 상태에서 삭제처리 this.removeCache(); } return false; }, restoreCache: function() { // sessionStorage 지원 여부 확인 if (!window.sessionStorage) { return false; } // 데이터 복구 유무 var bRestored = false; try { // 데이터 복구 var oCache = JSON.parse(window.sessionStorage.getItem('member_' + EC_SDE_SHOP_NUM)); // expire 체크 if (oCache.exp < Date.now()) { throw 'cache has expired.'; } // 데이터 체크 if (typeof oCache.data.member_id === 'undefined' || oCache.data.member_id === '' || typeof oCache.data.name === 'undefined' || typeof oCache.data.nick_name === 'undefined' || typeof oCache.data.group_name === 'undefined' || typeof oCache.data.group_no === 'undefined' || typeof oCache.data.email === 'undefined' || typeof oCache.data.phone === 'undefined' || typeof oCache.data.cellphone === 'undefined' || typeof oCache.data.birthday === 'undefined' || typeof oCache.data.board_write_name === 'undefined' || typeof oCache.data.additional_information === 'undefined' || typeof oCache.data.created_date === 'undefined' ) { throw 'Invalid cache data.' } // 데이터 복구 this.__sMemberId = oCache.data.member_id; this.__sName = oCache.data.name; this.__sNickName = oCache.data.nick_name; this.__sGroupName = oCache.data.group_name; this.__sGroupNo = oCache.data.group_no; this.__sEmail = oCache.data.email; this.__sPhone = oCache.data.phone; this.__sCellphone = oCache.data.cellphone; this.__sBirthday = oCache.data.birthday; this.__sBoardWriteName = oCache.data.board_write_name; this.__sAdditionalInformation = oCache.data.additional_information; this.__sCreatedDate = oCache.data.created_date; bRestored = true; } catch(e) { // 복구 실패시 캐시 삭제 this.removeCache(); } return bRestored; }, cache: function() { // sessionStorage 지원 여부 확인 if (!window.sessionStorage) { return; } // 캐시 window.sessionStorage.setItem('member_' + EC_SDE_SHOP_NUM, JSON.stringify({ exp: Date.now() + (1000 * 60 * 10), data: this.getData() })); }, removeCache: function() { // sessionStorage 지원 여부 확인 if (!window.sessionStorage) { return; } // 캐시 삭제 window.sessionStorage.removeItem('member_' + EC_SDE_SHOP_NUM); }, setData: function(oData) { this.__sEncryptedString = oData.memberData; this.__isAdult = oData.memberIsAdult; }, execute: function() { if (this.__sMemberId === null) { AuthSSLManager.weave({ 'auth_mode' : 'decryptClient', 'auth_string' : this.__sEncryptedString, 'auth_callbackName' : 'CAPP_ASYNC_METHODS.member.setDataCallback' }); } else { this.render() } }, setDataCallback: function(sData) { try { var sDecodedData = decodeURIComponent(sData); if (AuthSSLManager.isError(sDecodedData) == true) { console.log(sDecodedData); return; } var oData = AuthSSLManager.unserialize(sDecodedData); this.__sMemberId = oData.id || ''; this.__sName = oData.name || ''; this.__sNickName = oData.nick || ''; this.__sGroupName = oData.group_name || ''; this.__sGroupNo = oData.group_no || ''; this.__sEmail = oData.email || ''; this.__sPhone = oData.phone || ''; this.__sCellphone = oData.cellphone || ''; this.__sBirthday = oData.birthday || 'F'; this.__sBoardWriteName = oData.board_write_name || ''; this.__sAdditionalInformation = oData.additional_information || ''; this.__sCreatedDate = oData.created_date || ''; // 데이터 랜더링 this.render(); // 데이터 캐시 this.cache(); } catch(e) {} }, render: function() { // 친구초대 if ($('.xans-myshop-asyncbenefit').length > 0) { $('#reco_url').attr({value: $('#reco_url').val() + this.__sMemberId}); } $('.xans-member-var-id').html(this.__sMemberId); $('.xans-member-var-name').html(this.__sName); $('.xans-member-var-nick').html(this.__sNickName); $('.xans-member-var-group_name').html(this.__sGroupName); $('.xans-member-var-group_no').html(this.__sGroupNo); $('.xans-member-var-email').html(this.__sEmail); $('.xans-member-var-phone').html(this.__sPhone); if ($('.xans-board-commentwrite').length > 0 && typeof BOARD_COMMENT !== 'undefined') { BOARD_COMMENT.setCmtData(); } }, getMemberIsAdult: function() { return this.__isAdult; }, getData: function() { return { member_id: this.__sMemberId, name: this.__sName, nick_name: this.__sNickName, group_name: this.__sGroupName, group_no: this.__sGroupNo, email: this.__sEmail, phone: this.__sPhone, cellphone: this.__sCellphone, birthday: this.__sBirthday, board_write_name: this.__sBoardWriteName, additional_information: this.__sAdditionalInformation, created_date: this.__sCreatedDate }; } }; /** * 비동기식 데이터 - 예치금 */ CAPP_ASYNC_METHODS.aDatasetList.push('Ordercnt'); CAPP_ASYNC_METHODS.Ordercnt = { __iOrderShppiedBeforeCount: null, __iOrderShppiedStandbyCount: null, __iOrderShppiedBeginCount: null, __iOrderShppiedComplateCount: null, __iOrderShppiedCancelCount: null, __iOrderShppiedExchangeCount: null, __iOrderShppiedReturnCount: null, __$target: $('#xans_myshop_orderstate_shppied_before_count'), __$target2: $('#xans_myshop_orderstate_shppied_standby_count'), __$target3: $('#xans_myshop_orderstate_shppied_begin_count'), __$target4: $('#xans_myshop_orderstate_shppied_complate_count'), __$target5: $('#xans_myshop_orderstate_order_cancel_count'), __$target6: $('#xans_myshop_orderstate_order_exchange_count'), __$target7: $('#xans_myshop_orderstate_order_return_count'), isUse: function() { if ($('.xans-myshop-orderstate').length > 0) { return true; } return false; }, restoreCache: function() { var sCookieName = 'ordercnt_' + EC_SDE_SHOP_NUM; var re = new RegExp('(?:^| |;)' + sCookieName + '=([^;]+)'); var aCookieValue = document.cookie.match(re); if (aCookieValue) { var aData = jQuery.parseJSON(decodeURIComponent(aCookieValue[1])); this.__iOrderShppiedBeforeCount = aData.shipped_before_count; this.__iOrderShppiedStandbyCount = aData.shipped_standby_count; this.__iOrderShppiedBeginCount = aData.shipped_begin_count; this.__iOrderShppiedComplateCount = aData.shipped_complate_count; this.__iOrderShppiedCancelCount = aData.order_cancel_count; this.__iOrderShppiedExchangeCount = aData.order_exchange_count; this.__iOrderShppiedReturnCount = aData.order_return_count; return true; } return false; }, setData: function(aData) { this.__iOrderShppiedBeforeCount = aData['shipped_before_count']; this.__iOrderShppiedStandbyCount = aData['shipped_standby_count']; this.__iOrderShppiedBeginCount = aData['shipped_begin_count']; this.__iOrderShppiedComplateCount = aData['shipped_complate_count']; this.__iOrderShppiedCancelCount = aData['order_cancel_count']; this.__iOrderShppiedExchangeCount = aData['order_exchange_count']; this.__iOrderShppiedReturnCount = aData['order_return_count']; }, execute: function() { this.__$target.html(this.__iOrderShppiedBeforeCount); this.__$target2.html(this.__iOrderShppiedStandbyCount); this.__$target3.html(this.__iOrderShppiedBeginCount); this.__$target4.html(this.__iOrderShppiedComplateCount); this.__$target5.html(this.__iOrderShppiedCancelCount); this.__$target6.html(this.__iOrderShppiedExchangeCount); this.__$target7.html(this.__iOrderShppiedReturnCount); }, getData: function() { return { shipped_before_count: this.__iOrderShppiedBeforeCount, shipped_standby_count: this.__iOrderShppiedStandbyCount, shipped_begin_count: this.__iOrderShppiedBeginCount, shipped_complate_count: this.__iOrderShppiedComplateCount, order_cancel_count: this.__iOrderShppiedCancelCount, order_exchange_count: this.__iOrderShppiedExchangeCount, order_return_count: this.__iOrderShppiedReturnCount }; } }; /** * 비동기식 데이터 - 장바구니 갯수 */ CAPP_ASYNC_METHODS.aDatasetList.push('Basketcnt'); CAPP_ASYNC_METHODS.Basketcnt = { __iBasketCount: null, __$target: $('.xans-layout-orderbasketcount span a'), __$target2: $('#xans_myshop_basket_cnt'), __$target3: CAPP_ASYNC_METHODS.$xansMyshopMain.find('.xans_myshop_main_basket_cnt'), __$target4: $('.EC-Layout-Basket-count'), isUse: function() { if (this.__$target.length > 0) { return true; } if (this.__$target2.length > 0) { return true; } if (this.__$target3.length > 0) { return true; } if (this.__$target4.length > 0) { return true; } if ( typeof EC_APPSCRIPT_SDK_DATA != "undefined" && jQuery.inArray('personal', EC_APPSCRIPT_SDK_DATA ) > -1 ) { return true; } return false; }, restoreCache: function() { var sCookieName = 'basketcount_' + EC_SDE_SHOP_NUM; var re = new RegExp('(?:^| |;)' + sCookieName + '=([^;]+)'); var aCookieValue = document.cookie.match(re); if (aCookieValue) { this.__iBasketCount = parseInt(aCookieValue[1], 10); return true; } return false; }, setData: function(sData) { this.__iBasketCount = Number(sData); }, execute: function() { this.__$target.html(this.__iBasketCount); if (SHOP.getLanguage() === 'ko_KR') { this.__$target2.html(this.__iBasketCount + '개'); } else { this.__$target2.html(this.__iBasketCount); } this.__$target3.html(this.__iBasketCount); this.__$target4.html(this.__iBasketCount); if (this.__iBasketCount > 0 && this.__$target4.length > 0) { var $oCountDisplay = $('.EC-Layout_Basket-count-display'); if ($oCountDisplay.length > 0) { $oCountDisplay.removeClass('displaynone'); } } }, getData: function() { return { count: this.__iBasketCount }; } }; /** * 비동기식 데이터 - 장바구니 금액 */ CAPP_ASYNC_METHODS.aDatasetList.push('Basketprice'); CAPP_ASYNC_METHODS.Basketprice = { __sBasketPrice: null, __$target: $('#xans_myshop_basket_price'), isUse: function() { if (this.__$target.length > 0) { return true; } if ( typeof EC_APPSCRIPT_SDK_DATA != "undefined" && jQuery.inArray('personal', EC_APPSCRIPT_SDK_DATA ) > -1 ) { return true; } return false; }, restoreCache: function() { var sCookieName = 'basketprice_' + EC_SDE_SHOP_NUM; var re = new RegExp('(?:^| |;)' + sCookieName + '=([^;]+)'); var aCookieValue = document.cookie.match(re); if (aCookieValue) { this.__sBasketPrice = decodeURIComponent((aCookieValue[1]+ '').replace(/\+/g, '%20')); return true; } return false; }, setData: function(sData) { this.__sBasketPrice = sData; }, execute: function() { this.__$target.html(this.__sBasketPrice); }, getData: function() { // 데이터 없는경우 0 var sBasketPrice = (this.__sBasketPrice || 0) + ''; return { basket_price: parseFloat(SHOP_PRICE_FORMAT.detachFormat(htmlentities.decode(sBasketPrice))).toFixed(2) }; } }; /* * 비동기식 데이터 - 장바구니 상품리스트 */ CAPP_ASYNC_METHODS.aDatasetList.push('BasketProduct'); CAPP_ASYNC_METHODS.BasketProduct = { STORAGE_KEY: 'BasketProduct_' + EC_SDE_SHOP_NUM, __aData: null, __$target: $('.xans-layout-orderbasketcount span a'), __$target2: $('#xans_myshop_basket_cnt'), __$target3: CAPP_ASYNC_METHODS.$xansMyshopMain.find('.xans_myshop_main_basket_cnt'), __$target4: $('.EC-Layout-Basket-count'), isUse: function() { if (this.__$target.length > 0) { return true; } if (this.__$target2.length > 0) { return true; } if (this.__$target3.length > 0) { return true; } if (this.__$target4.length > 0) { return true; } if ( typeof EC_APPSCRIPT_SDK_DATA != "undefined" && jQuery.inArray('personal', EC_APPSCRIPT_SDK_DATA ) > -1 ) { return true; } }, restoreCache: function() { // sessionStorage 지원 여부 확인 if (!window.sessionStorage) { return false; } var sSessionStorageData = window.sessionStorage.getItem(this.STORAGE_KEY); if (sSessionStorageData === null) { return false; } try { this.__aData = []; var aStorageData = JSON.parse(sSessionStorageData); for (var iKey in aStorageData) { this.__aData.push(aStorageData[iKey]); } return true; } catch(e) { // 복구 실패시 캐시 삭제 this.removeCache(); return false; } }, removeCache: function() { // sessionStorage 지원 여부 확인 if (!window.sessionStorage) { return; } // 캐시 삭제 window.sessionStorage.removeItem(this.STORAGE_KEY); }, setData: function(oData) { this.__aData = oData; // sessionStorage 지원 여부 확인 if (!window.sessionStorage) { return; } try { sessionStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.getData())); } catch (error) { } }, execute: function() { }, getData: function() { var aStorageData = this.__aData; if (aStorageData != null) { var oNewStorageData = []; for (var iKey in aStorageData) { oNewStorageData.push(aStorageData[iKey]); } return oNewStorageData; } else { return false; } } }; /** * 비동기식 데이터 - 쿠폰 갯수 */ CAPP_ASYNC_METHODS.aDatasetList.push('Couponcnt'); CAPP_ASYNC_METHODS.Couponcnt = { __iCouponCount: null, __$target: $('.xans-layout-myshopcouponcount'), __$target2: $('#xans_myshop_coupon_cnt'), __$target3: CAPP_ASYNC_METHODS.$xansMyshopMain.find('.xans_myshop_main_coupon_cnt'), __$target4: $('#xans_myshop_bankbook_coupon_cnt'), isUse: function() { if (CAPP_ASYNC_METHODS.IS_LOGIN === true) { if (this.__$target.length > 0) { return true; } if (this.__$target2.length > 0) { return true; } if (this.__$target3.length > 0) { return true; } if (this.__$target4.length > 0) { return true; } if ( typeof EC_APPSCRIPT_SDK_DATA != "undefined" && jQuery.inArray('promotion', EC_APPSCRIPT_SDK_DATA ) > -1 ) { return true; } } return false; }, restoreCache: function() { var sCookieName = 'couponcount_' + EC_SDE_SHOP_NUM; var re = new RegExp('(?:^| |;)' + sCookieName + '=([^;]+)'); var aCookieValue = document.cookie.match(re); if (aCookieValue) { this.__iCouponCount = parseInt(aCookieValue[1], 10); return true; } return false; }, setData: function(sData) { this.__iCouponCount = Number(sData); }, execute: function() { this.__$target.html(this.__iCouponCount); if (SHOP.getLanguage() === 'ko_KR') { this.__$target2.html(this.__iCouponCount + '개'); } else { this.__$target2.html(this.__iCouponCount); } this.__$target3.html(this.__iCouponCount); this.__$target4.html(this.__iCouponCount); }, getData: function() { return { count: this.__iCouponCount }; } }; /** * 비동기식 데이터 - 적립금 */ CAPP_ASYNC_METHODS.aDatasetList.push('Mileage'); CAPP_ASYNC_METHODS.Mileage = { __sAvailMileage: null, __sUsedMileage: null, __sTotalMileage: null, __sUnavailMileage: null, __sReturnedMileage: null, __$target: $('#xans_myshop_mileage'), __$target2: $('#xans_myshop_bankbook_avail_mileage, #xans_myshop_summary_avail_mileage'), __$target3: $('#xans_myshop_bankbook_used_mileage, #xans_myshop_summary_used_mileage'), __$target4: $('#xans_myshop_bankbook_total_mileage, #xans_myshop_summary_total_mileage'), __$target5: $('#xans_myshop_summary_unavail_mileage'), __$target6: $('#xans_myshop_summary_returned_mileage'), __$target7: $('#xans_myshop_avail_mileage'), isUse: function() { if (CAPP_ASYNC_METHODS.IS_LOGIN === true) { if (this.__$target.length > 0) { return true; } if (this.__$target2.length > 0) { return true; } if (this.__$target3.length > 0) { return true; } if (this.__$target4.length > 0) { return true; } if (this.__$target5.length > 0) { return true; } if (this.__$target6.length > 0) { return true; } if (this.__$target7.length > 0) { return true; } if ( typeof EC_APPSCRIPT_SDK_DATA != "undefined" && jQuery.inArray('customer', EC_APPSCRIPT_SDK_DATA ) > -1 ) { return true; } } return false; }, restoreCache: function() { // 특정 경로 룰의 경우 복구 취소 if (PathRoleValidator.isInvalidPathRole()) { return false; } // 쿠키로부터 데이터 획득 var sAvailMileage = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_avail_mileage_' + EC_SDE_SHOP_NUM); var sReturnedMileage = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_returned_mileage_' + EC_SDE_SHOP_NUM); var sUnavailMileage = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_unavail_mileage_' + EC_SDE_SHOP_NUM); var sUsedMileage = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_used_mileage_' + EC_SDE_SHOP_NUM); // 데이터가 하나라도 없는경우 복구 실패 if (sAvailMileage === null || sReturnedMileage === null || sUnavailMileage === null || sUsedMileage === null ) { return false; } // 전체 마일리지 계산 var sTotalMileage = (parseFloat(sAvailMileage) + parseFloat(sUnavailMileage) + parseFloat(sUsedMileage)).toString(); // 단위정보를 계산하여 필드에 셋 this.__sAvailMileage = parseFloat(sAvailMileage).toFixed(2); this.__sReturnedMileage = parseFloat(sReturnedMileage).toFixed(2); this.__sUnavailMileage = parseFloat(sUnavailMileage).toFixed(2); this.__sUsedMileage = parseFloat(sUsedMileage).toFixed(2); this.__sTotalMileage = parseFloat(sTotalMileage).toFixed(2); return true; }, setData: function(aData) { this.__sAvailMileage = parseFloat(aData['avail_mileage'] || 0).toFixed(2); this.__sUsedMileage = parseFloat(aData['used_mileage'] || 0).toFixed(2); this.__sTotalMileage = parseFloat(aData['total_mileage'] || 0).toFixed(2); this.__sUnavailMileage = parseFloat(aData['unavail_mileage'] || 0).toFixed(2); this.__sReturnedMileage = parseFloat(aData['returned_mileage'] || 0).toFixed(2); }, execute: function() { this.__$target.html(SHOP_PRICE_FORMAT.toShopMileagePrice(this.__sAvailMileage)); this.__$target2.html(SHOP_PRICE_FORMAT.toShopMileagePrice(this.__sAvailMileage)); this.__$target3.html(SHOP_PRICE_FORMAT.toShopMileagePrice(this.__sUsedMileage)); this.__$target4.html(SHOP_PRICE_FORMAT.toShopMileagePrice(this.__sTotalMileage)); this.__$target5.html(SHOP_PRICE_FORMAT.toShopMileagePrice(this.__sUnavailMileage)); this.__$target6.html(SHOP_PRICE_FORMAT.toShopMileagePrice(this.__sReturnedMileage)); this.__$target7.html(SHOP_PRICE_FORMAT.toShopMileagePrice(this.__sAvailMileage)); }, getData: function() { return { available_mileage: this.__sAvailMileage, used_mileage: this.__sUsedMileage, total_mileage: this.__sTotalMileage, returned_mileage: this.__sReturnedMileage, unavailable_mileage: this.__sUnavailMileage }; } }; /** * 비동기식 데이터 - 예치금 */ CAPP_ASYNC_METHODS.aDatasetList.push('Deposit'); CAPP_ASYNC_METHODS.Deposit = { __sTotalDeposit: null, __sAllDeposit: null, __sUsedDeposit: null, __sRefundWaitDeposit: null, __sMemberTotalDeposit: null, __$target: $('#xans_myshop_deposit'), __$target2: $('#xans_myshop_bankbook_deposit'), __$target3: $('#xans_myshop_summary_deposit'), __$target4: $('#xans_myshop_summary_all_deposit'), __$target5: $('#xans_myshop_summary_used_deposit'), __$target6: $('#xans_myshop_summary_refund_wait_deposit'), __$target7: $('#xans_myshop_total_deposit'), isUse: function() { if (CAPP_ASYNC_METHODS.IS_LOGIN === true) { if (this.__$target.length > 0) { return true; } if (this.__$target2.length > 0) { return true; } if (this.__$target3.length > 0) { return true; } if (this.__$target4.length > 0) { return true; } if (this.__$target5.length > 0) { return true; } if (this.__$target6.length > 0) { return true; } if (this.__$target7.length > 0) { return true; } if ( typeof EC_APPSCRIPT_SDK_DATA != "undefined" && jQuery.inArray('customer', EC_APPSCRIPT_SDK_DATA ) > -1 ) { return true; } } return false; }, restoreCache: function() { // 특정 경로 룰의 경우 복구 취소 if (PathRoleValidator.isInvalidPathRole()) { return false; } // 쿠키로부터 데이터 획득 var sAllDeposit = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_all_deposit_' + EC_SDE_SHOP_NUM); var sUsedDeposit = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_used_deposit_' + EC_SDE_SHOP_NUM); var sRefundWaitDeposit = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_deposit_refund_wait_' + EC_SDE_SHOP_NUM); var sMemberTotalDeposit = CAPP_ASYNC_METHODS._getCookie('ec_async_cache_member_total_deposit_' + EC_SDE_SHOP_NUM); // 데이터가 하나라도 없는경우 복구 실패 if (sAllDeposit === null || sUsedDeposit === null || sRefundWaitDeposit === null || sMemberTotalDeposit === null ) { return false; } // 사용 가능한 예치금 계산 var sTotalDeposit = (parseFloat(sAllDeposit) - parseFloat(sUsedDeposit) - parseFloat(sRefundWaitDeposit)).toString(); // 단위정보를 계산하여 필드에 셋 this.__sTotalDeposit = parseFloat(sTotalDeposit).toFixed(2); this.__sAllDeposit = parseFloat(sAllDeposit).toFixed(2); this.__sUsedDeposit = parseFloat(sUsedDeposit).toFixed(2); this.__sRefundWaitDeposit = parseFloat(sRefundWaitDeposit).toFixed(2); this.__sMemberTotalDeposit = parseFloat(sMemberTotalDeposit).toFixed(2); return true; }, setData: function(aData) { this.__sTotalDeposit = parseFloat(aData['total_deposit'] || 0).toFixed(2); this.__sAllDeposit = parseFloat(aData['all_deposit'] || 0).toFixed(2); this.__sUsedDeposit = parseFloat(aData['used_deposit'] || 0).toFixed(2); this.__sRefundWaitDeposit = parseFloat(aData['deposit_refund_wait'] || 0).toFixed(2); this.__sMemberTotalDeposit = parseFloat(aData['member_total_deposit'] || 0).toFixed(2); }, execute: function() { this.__$target.html(SHOP_PRICE_FORMAT.toShopDepositPrice(this.__sTotalDeposit)); this.__$target2.html(SHOP_PRICE_FORMAT.toShopDepositPrice(this.__sTotalDeposit)); this.__$target3.html(SHOP_PRICE_FORMAT.toShopDepositPrice(this.__sTotalDeposit)); this.__$target4.html(SHOP_PRICE_FORMAT.toShopDepositPrice(this.__sAllDeposit)); this.__$target5.html(SHOP_PRICE_FORMAT.toShopDepositPrice(this.__sUsedDeposit)); this.__$target6.html(SHOP_PRICE_FORMAT.toShopDepositPrice(this.__sRefundWaitDeposit)); this.__$target7.html(SHOP_PRICE_FORMAT.toShopDepositPrice(this.__sMemberTotalDeposit)); }, getData: function() { return { total_deposit: this.__sTotalDeposit, used_deposit: this.__sUsedDeposit, refund_wait_deposit: this.__sRefundWaitDeposit, all_deposit: this.__sAllDeposit, member_total_deposit: this.__sMemberTotalDeposit }; } }; /** * 비동기식 데이터 - 위시리스트 */ CAPP_ASYNC_METHODS.aDatasetList.push('WishList'); CAPP_ASYNC_METHODS.WishList = { STORAGE_KEY: 'localWishList' + EC_SDE_SHOP_NUM, __$targetWishIcon: $('.icon_img.ec-product-listwishicon'), __$targetWishList: $('.xans-myshop-wishlist'), __aWishList: null, __aTags_on: null, __aTags_off: null, isUse: function() { if (this.__$targetWishIcon.length > 0 || this.__$targetWishList.length > 0) { return true; } return false; }, restoreCache: function() { if (!window.sessionStorage) { return false; } var sSessionStorageData = window.sessionStorage.getItem(this.STORAGE_KEY); if (sSessionStorageData === null) { return false; } var aStorageData = $.parseJSON(sSessionStorageData); if (this.__$targetWishList.length > 0 || aStorageData['isLogin'] !== CAPP_ASYNC_METHODS.IS_LOGIN) { this.clearStorage(); return false; } if (CAPP_ASYNC_METHODS.EC_PATH_ROLE === 'MAIN') { var aWishList = aStorageData['wishList']; this.__aTags_on = aStorageData['on_tags']; this.__aTags_off = aStorageData['off_tags']; this.__aWishList = []; for (var i = 0; i < aWishList.length; i++) { var aTempWishList = []; aTempWishList.product_no = aWishList[i]; this.__aWishList.push(aTempWishList); } return true; } return false; }, setData: function(aData) { if (aData.hasOwnProperty('wishList') === false || aData.hasOwnProperty('on_tags') === false) { return; } this.__aWishList = aData.wishList; this.__aTags_on = aData.on_tags; this.__aTags_off = aData.off_tags; if (window.sessionStorage) { var aWishList = []; for (var i = 0 ; i < aData.wishList.length ; i++) { aWishList.push(aData.wishList[i].product_no); } var oNewStorageData = { 'wishList' : aWishList, 'on_tags' : aData.on_tags, 'off_tags' : aData.off_tags, 'isLogin' : CAPP_ASYNC_METHODS.IS_LOGIN }; if (typeof oNewStorageData !== 'undefined') { sessionStorage.setItem(this.STORAGE_KEY , JSON.stringify(oNewStorageData)); } } }, execute: function() { var aWishList = this.__aWishList; var aTagsOn = this.__aTags_on; var aTagsOff = this.__aTags_off; if (aWishList === null || typeof aWishList === 'undefined') { aWishList = []; } var oTarget = $('.ec-product-listwishicon'); for (var sKey in aTagsOff) { oTarget.attr(sKey, aTagsOff[sKey]); } for (var i = 0 ; i < aWishList.length ; i++) { assignAttribute(aWishList[i]); } /** * oTarget 엘레먼트에 aData의 정보를 어싸인함. * @param array aData 위시리스트 정보 */ function assignAttribute(aData) { var iProductNo = aData['product_no']; var oTarget = $('.ec-product-listwishicon:[productno="'+iProductNo+'"]'); // oTarget의 src, alt, icon_status attribute의 값을 할당 for (var sKey in aTagsOn) { oTarget.attr(sKey, aTagsOn[sKey]); } } }, /** * 세션스토리지 삭제 */ clearStorage: function() { if (!window.sessionStorage) { return; } window.sessionStorage.removeItem(this.STORAGE_KEY); }, /** * sCommand에 따른 sessionStorage Set * @param iProductNo * @param sCommand 추가(add)/삭제(del) sCommand */ setSessionStorageItem: function(iProductNo, sCommand) { if (this.isUse() === false) { return; } var oStorageData = $.parseJSON(sessionStorage.getItem(this.STORAGE_KEY)); var aWishList = oStorageData['wishList']; var iLimit = 200; if (aWishList === null) { aWishList = []; } var iProductNo = parseInt(iProductNo, 10); var iIndex = aWishList.indexOf(iProductNo); if (sCommand === 'add') { if (aWishList.length >= iLimit) { aWishList.splice(aWishList.length - 1, 1); } if (iIndex < 0) { aWishList.unshift(iProductNo); } } else { if (iIndex > -1) { aWishList.splice(iIndex, 1); } } oStorageData['wishList'] = aWishList; sessionStorage.setItem(this.STORAGE_KEY, JSON.stringify(oStorageData)); } };